package com.mes.schedule.manager;

import java.awt.Color;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.mes.basicdata.dao.DeviceDao;
import com.mes.basicdata.dao.WorkCenterDao;
import com.mes.basicdata.domain.Device;
import com.mes.basicdata.domain.OperationDevice;
import com.mes.basicdata.domain.WorkCenter;
import com.mes.common.exception.bo.BaseBusinessException;
import com.mes.common.exception.db.BaseDBException;
import com.mes.common.manager.BasicManager;
import com.mes.common.model.ObjectOperation;
import com.mes.common.util.SysUtil;
import com.mes.schedule.algorithm.PriorityCalc;
import com.mes.schedule.algorithm.ScheduleStateFind;
import com.mes.schedule.algorithm.TaskSFCalc;
import com.mes.schedule.dao.ScheduleEventDao;
import com.mes.schedule.dao.ScheduleOverTimeDao;
import com.mes.schedule.dao.ScheduleUtilizeDao;
import com.mes.schedule.domain.DeviceTable;
import com.mes.schedule.domain.McDevice;
import com.mes.schedule.domain.MtDevice;
import com.mes.schedule.domain.ResourceConstraint;
import com.mes.schedule.domain.SCalendar;
import com.mes.schedule.domain.SDevice;
import com.mes.schedule.domain.SGroupOperationTask;
import com.mes.schedule.domain.SOperationLink;
import com.mes.schedule.domain.SOperationTask;
import com.mes.schedule.domain.SPartTask;
import com.mes.schedule.domain.SVirtualLink;
import com.mes.schedule.domain.SWorkCenter;
import com.mes.schedule.domain.ScheduleEvent;
import com.mes.schedule.domain.ScheduleScheme;
import com.mes.schedule.domain.UcDevice;
import com.mes.schedule.manager.iface.IScheduleManager;
import com.mes.schedule.mt.TaskScheduleComparator;
import com.mes.schedule.mt.TaskScheduleComparatorSTF;
import com.mes.schedule.result.ScheduleResult;
import com.mes.schedule.sbt.SDisjunctiveLink;
import com.mes.schedule.sbt.TaskSink;
import com.mes.schedule.util.ScheduleUtils;
import com.mes.schedule.dao.ScheduleSchemeDao;
import com.mes.schedule.dao.STaskDao;
import com.mes.schedule.dao.SOperationLinkDao;
import com.mes.schedule.dao.SOperationTaskDao;
import com.mes.schedule.dao.SPartTaskDao;

@Component("scheduleManager")
@Transactional
public class ScheduleManager extends BasicManager implements IScheduleManager{
	public final static int THREAD_TYPE_FIXED10 = 10;
	public final static int THREAD_TYPE_FIXED20 = 20;
	public final static int THREAD_TYPE_FIXED50 = 50;
	public final static int THREAD_TYPE_UNLIMITED = 100;
	
	public final static Log log = LogFactory.getLog(ScheduleManager.class);
	protected String algorithmName = "普通优先级算法";
	@javax.annotation.Resource
	protected ScheduleSchemeDao ScheduleSchemeDao;
	@javax.annotation.Resource
	public STaskDao STaskDao;
	@javax.annotation.Resource
	protected DeviceDao deviceDao;
	@javax.annotation.Resource
	public WorkCenterDao workCenterDao;
	@javax.annotation.Resource
	protected AssignManager assignManager;
	@javax.annotation.Resource
	public ScheduleOperationTaskManager scheduleOperationTaskManager;
	@javax.annotation.Resource
	protected SchedulePartTaskManager schedulePartTaskManager;
	@javax.annotation.Resource
	protected SOperationTaskDao SOperationTaskDao;
	@javax.annotation.Resource
	public SPartTaskDao schedulePartTaskDao;
	@javax.annotation.Resource
	public SOperationLinkDao scheduleOperationLinkDao;
	@javax.annotation.Resource
	public ScheduleUtilizeDao scheduleUtilizeDao;
	@javax.annotation.Resource
	protected ReadyTaskManager readyTaskManager;
	@javax.annotation.Resource
	protected ScheduleDeviceManager scheduledeviceManager;
	@javax.annotation.Resource
	protected ScheduleAnalysis scheduleAnalysis;
	@javax.annotation.Resource
	public TaskSFCalc taskSFCalc;
	@javax.annotation.Resource
	public PriorityCalc priorityCalc;
	@javax.annotation.Resource
	protected ScheduleCalendarManager scheduleCalendarManager;
	@javax.annotation.Resource
	protected ScheduleLinkManager scheduleLinkManager;
	@javax.annotation.Resource
	public ScheduleOverTimeDao scheduleOverTimeDao;
	@javax.annotation.Resource
	private ScheduleEventDao scheduleEventDao;
	@javax.annotation.Resource
	private ScheduleStateFind scheduleStateFind;
	@javax.annotation.Resource
	protected ScheduleEventManager scheduleEventManager;

	protected int threadType = THREAD_TYPE_FIXED10;

	// protected TaskBCManager taskBCManager;
	/**
	 * @param ScheduleSchemeDao
	 *            the ScheduleSchemeDao to set
	 */
	public void setScheduleDao(ScheduleSchemeDao ScheduleSchemeDao) {

		this.ScheduleSchemeDao = ScheduleSchemeDao;
		this.basicDao = ScheduleSchemeDao;
	}

	/**
	 * @param deviceDao
	 *            the deviceDao to set
	 */
	public void setDeviceDao(DeviceDao deviceDao) {
		this.deviceDao = deviceDao;
	}

	/**
	 * @param assignManager
	 *            the assignManager to set
	 */
	public void setAssignManager(AssignManager assignManager) {
		this.assignManager = assignManager;
	}

	public void setScheduleCalendarManager(
			ScheduleCalendarManager scheduleCalendarManager) {
		this.scheduleCalendarManager = scheduleCalendarManager;
	}

	/**
	 * @param STaskDao
	 *            the STaskDao to set
	 */
	public void setScheduleTaskDao(STaskDao STaskDao) {
		this.STaskDao = STaskDao;
	}

	/**
	 * @param scheduleOperationTaskManager
	 *            the scheduleOperationTaskManager to set
	 */
	public void setScheduleOperationTaskManager(
			ScheduleOperationTaskManager scheduleOperationTaskManager) {
		this.scheduleOperationTaskManager = scheduleOperationTaskManager;
	}

	/**
	 * @param schedulePartTaskManager
	 *            the schedulePartTaskManager to set
	 */
	public void setSchedulePartTaskManager(
			SchedulePartTaskManager schedulePartTaskManager) {
		this.schedulePartTaskManager = schedulePartTaskManager;
	}

	/**
	 * @param deviceManager
	 *            the deviceManager to set
	 */
	public void setDeviceManager(ScheduleDeviceManager scheduledeviceManager) {
		this.scheduledeviceManager = scheduledeviceManager;
	}

	/**
	 * @param scheduleAnalysis
	 *            the scheduleAnalysis to set
	 */
	public void setScheduleAnalysis(ScheduleAnalysis scheduleAnalysis) {
		this.scheduleAnalysis = scheduleAnalysis;
	}

	/**
	 * get the schedule scheme by scheduleUid
	 * 
	 * @param scheduleUid
	 * @return ScheduleScheme
	 * @throws Exception 
	 * @see com.mes.schedule.manager.iface.ScheduleManager#getScheduleByUid(java.lang.String)
	 */
	public ScheduleScheme getScheduleByUid(String scheduleUid)
			throws Exception {
		List<ScheduleScheme> list =  this.ScheduleSchemeDao.findByProperty(
				"scheduleUid", scheduleUid);

		if (list == null || list.size() == 0) {
			//暂时注视掉 hba 继承计划时如果找不到基准计划，则无法打开，改为return null
			return null;
			//throw new BaseDBException("无法找到调度方案，请重新登录后再试!");
		} else {
			ScheduleScheme scheme = list.get(0);
			if (scheme.getMaxOverlap() == null)
				scheme.setMaxOverlap(0.1);
			if (scheme.getScheduleDays() == null)
				scheme.setScheduleDays(30);
			return scheme;
		}
	}

	// 应该改名为初始化
	public void importTasks(ScheduleScheme scheme) throws Exception {
		this.initVirtualResource(scheme);
		initWorkCenterMap(scheme);
//		deviceDao.initDeviceMap(scheme);
		// load tasks or update tasks
		STaskDao.initTasks(scheme);

		// 设置调度更新时间，最后关闭调度时保存该时间
		scheme.setLastUpdateTime(new Date());

		schemeDataPro(scheme);

	}

	public List<ScheduleResult> doSchedule(ScheduleScheme scheme, int mode)
			throws Exception {
		long lStart = System.currentTimeMillis();
		Boolean success = null;
		Future<Boolean> future = null;
		if (scheme == null)
			return null;
		List<ScheduleResult> scheduleResultList = null;
		
		
		//这个scheduleState是怎么得到的？ SnowBear，一直都是running
		/*if (scheme.getScheduleState().equals(
				ScheduleScheme.SCHEDULESTATE_RUNNING))
			throw new Exception("上次调度运算还正在进行中，请稍后重试!");*/
		// lqm todo
		// 好像不能立刻shuntdown,所以无法重用scheme中的服务线程
		// 对aps应用高级的线程策略
		ExecutorService executorService = ScheduleUtils
				.getExecutorService(scheme);

		if (executorService == null)
			throw new Exception("未定义调度算法运行的线程池!");

		try {
			log.debug("开始进行调度");

			scheme.setScheduleState(ScheduleScheme.SCHEDULESTATE_RUNNING);

			log.info("算法名称为：" + this.algorithmName);

			ScheduleThread scheduleThread = new ScheduleThread(this, scheme,
					mode);

			//future = executorService.submit((Callable<ScheduleThread>) scheduleThread);
			//在此处添加了继承关系scheduleThread继承Thread,然后将其强制转换成future类型
			future =  executorService.submit(scheduleThread);
			// 调度最多运行5分钟后
			// 5分钟后关掉所有相关线程
			int maxWaitTime = 15;
			if (log.isDebugEnabled()) {
				maxWaitTime = 1200;
			}
			success =  future.get(maxWaitTime, TimeUnit.MINUTES);
			// Boolean success = future.get(10, TimeUnit.SECONDS);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			log.error(e);
			future.cancel(true);
		} catch (ExecutionException e) {
			// TODO Auto-gen;erated catch block
			log.error(e);
			future.cancel(true);
		} catch (TimeoutException e) {
			String msg = " 本次调度由于超时被取消，请检查调度任务是否出现循环链接！\n";
			SOperationTask maxTask = this.getMaxScheduleCountTask(scheme);
			if (maxTask != null)
				msg += "请重点检查相关任务序列设置 ：" + maxTask.toFriendlyString();
			future.cancel(true);
			throw new Exception(msg);
		} finally {
			scheme.setScheduleState(ScheduleScheme.SCHEDULESTATE_OPENED);
		}

		if (success!=null) {

			ScheduleResult scheduleResult = new ScheduleResult();
			scheduleResult.setScheme(scheme);
			scheduleResult.setAlgorithmName(this.algorithmName);
			this.calPartTaskTime(scheme);

			scheduleResult.setTotalPartTaskCount(scheme.getSchedulePartTasks()
					.size());

			int lagCount = 0;
			for (SPartTask partTask : scheme.getSchedulePartTasks()) {
				if (partTask.getLateFinish() != null
						&& partTask.getPlanFinish() != null
						&& partTask.getPlanFinish().after(
								partTask.getLateFinish()))
					lagCount++;
			}

			scheduleResult.setTotalLagPartTaskCount(lagCount);

			scheduleResult.setTargetValue(scheduleAnalysis
					.calcTargetValue(scheme));

			scheduleResult.setTwtCost(scheduleAnalysis.calcTwtValue(scheme));
			scheduleResult.setMakespanCount(scheduleAnalysis
					.calcMakeSpan(scheme));

			long lEnd = System.currentTimeMillis();
			long diff = (lEnd - lStart) / 1000;// 得到两者的秒数
			scheduleResult.setElapsedTime(diff);
			log.info("本次调度拖期惩罚代价为：" + scheduleResult.getTwtCost());
			log.info("本次共调度结束！用时  " + diff + "  秒");
			// lqm todo
			// 为能输出多个调度结果作准备
			scheduleResultList = new ArrayList<ScheduleResult>();
			scheduleResultList.add(scheduleResult);

			if (log.isDebugEnabled()) {

				log.debug("本次调度次数为：" + scheme.getTotalAssignCount()
						+ ",取消调度次数为：" + scheme.getTotalCancelAssignCount());
			}

			// log.info("开始根据调度结果自动生成班产任务-----------");
			// Map<String,SDevice> deviceMap=scheme.getDeviceMap();
			// String scheduleuid=scheme.getScheduleUid();
			// TaskBCManager taskBCManager =
			// SpringUtils.getBean("taskBCManager");
			// if(scheduleuid!=null)
			// {
			// for (String deviceuid :deviceMap.keySet())
			// {
			// if(deviceuid!="cooperation")
			// {
			// taskBCManager.clearTaskBC(scheme,deviceuid);
			// taskBCManager.genTaskBC(scheme,deviceuid);
			// }
			//					
			// }
			// }
			// diff = (System.currentTimeMillis() - lEnd) / 1000;// 得到两者的秒数
			// log.info("班产任务生成结束！用时 " + diff + " 秒");
		}

		return scheduleResultList;
	}

	private SOperationTask getMaxScheduleCountTask(ScheduleScheme scheme) {
		SOperationTask maxTask = null;
		int maxScheduleCount = 0;

		for (SOperationTask so : scheme.getScheduleOperationTasks()) {
			if (so.getScheduleCount() > maxScheduleCount) {
				maxTask = so;
				maxScheduleCount = so.getScheduleCount();
			}
		}
		return maxTask;

	}

	public void finishScheme(ScheduleScheme scheme) throws Exception {
		this.ScheduleSchemeDao.update(scheme);
	}

	@Transactional
	public void clearAllTask(String scheduleUid) throws BaseBusinessException {

		this.schedulePartTaskDao.deleteAllPartTask(scheduleUid);
		this.SOperationTaskDao.deleteAllOperationTask(scheduleUid);
		this.scheduleOperationLinkDao.deleteAllLink(scheduleUid);

	}

	@Transactional
	public Boolean save(Serializable object) throws BaseBusinessException {
		ScheduleScheme scheme = (ScheduleScheme) object;
		if (scheme.getScheduleStart() == null) {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(new Date());
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MILLISECOND, 0);
			scheme.setScheduleStart(calendar.getTime());
		}
		if (scheme.getScheduleFinish() == null) {
			// set scheduleFinish
			Calendar calendar1 = Calendar.getInstance();
			calendar1.setTime(scheme.getScheduleStart());
			calendar1.add(Calendar.YEAR, 1);
			scheme.setScheduleFinish(calendar1.getTime());
		}

		if (scheme.getScheduleType() == null) {
			scheme.setScheduleType(0);
		}

		if (scheme.getScheduleInterval() == null
				|| scheme.getScheduleInterval() == 0) {
			scheme.setScheduleInterval(15);
		}

		if (scheme.getWatchDays() == null) {
			scheme.setWatchDays(30);
		}

		if (scheme.getScheduleDays() == null) {
			scheme.setScheduleDays(7);
		}

		if (scheme.getWarningWaitDays() == null) {
			scheme.setWarningWaitDays(2);
		}

		if (scheme.getSlackType() == null) {
			scheme.setSlackType(0);
		}

		if (scheme.getAllowAutoPS() == null) {
			scheme.setAllowAutoPS(false);
		}

		if (scheme.getAutoPSSlack() == null) {
			scheme.setAutoPSSlack(0.5);
		}

		if (scheme.getAutoPSTaskLevel() == null) {
			scheme.setAutoPSTaskLevel(1);
		}

		if (scheme.getMaxOverlap() == null) {
			scheme.setMaxOverlap(0.1);
		}
		if (scheme.getAllowAutoOvertime() == null) {
			scheme.setAllowAutoOvertime(false);
		}
		if (scheme.getOvertimeTaskLevel() == null) {
			scheme.setOvertimeTaskLevel(1);
		}
		if (scheme.getOvertimeSlack() == null) {
			scheme.setOvertimeSlack(0.5);
		}

		try {
			this.ScheduleSchemeDao.save(scheme);
		} catch (BaseDBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	/**
	 * save the schedule result
	 */
	@Transactional
	public void saveResult(ScheduleScheme scheme) throws BaseBusinessException,
			BaseDBException {
		try {

			// STaskDao.saveTasks(scheme);

			// 采用更稳妥的存取数据方法
			// 只是记录更改时间
			List<SPartTask> persistensePartTaskList =  this.schedulePartTaskDao
					.findByProperty("scheduleUid", scheme.getScheduleUid());

			if (persistensePartTaskList != null
					&& persistensePartTaskList.size() > 0) {
				for (SPartTask persistensePartTask : persistensePartTaskList) {
					SPartTask partTask = scheme.getAllPartTaskMap().get(
							persistensePartTask.getTaskUid());
					if (partTask != null)
						ObjectOperation.copyAttributes(partTask,
								persistensePartTask, true);

					// && partTask.getTaskScheduleState() >=
					// SPartTask.TASKSCHEDULESTATE_STARTED) {
					// persistensePartTask.persistensePartTask
					// .setPlanStart(partTask.getPlanStart());
					// persistensePartTask.setPlanFinish(partTask
					// .getPlanFinish());
					// }
				}

			}

			List<SOperationTask> persistenseoperationTaskList =  this.SOperationTaskDao
					.findByProperty("scheduleUid", scheme.getScheduleUid());

			if (persistenseoperationTaskList != null
					&& persistenseoperationTaskList.size() > 0) {
				for (SOperationTask persistenseoperationTask : persistenseoperationTaskList) {
					SOperationTask operationTask = scheme
							.getAllOperationTaskMap().get(
									persistenseoperationTask.getTaskUid());

					if (operationTask != null) {
						ObjectOperation.copyAttributes(operationTask,
								persistenseoperationTask, true);
						// BeanUtils.copyProperties(persistenseoperationTask,
						// operationTask);
						// persistenseoperationTask.setTaskScheduleState(operationTask.getTaskScheduleState());
						// persistenseoperationTask.setSlackFactor(operationTask.getTaskScheduleState());
						// if (operationTask.getTaskScheduleState() >=
						// SOperationTask.TASKSCHEDULESTATE_STARTED) {
						// persistenseoperationTask.setPlanStart(operationTask
						// .getPlanStart());
						// persistenseoperationTask
						// .setPlanFinish(operationTask
						// .getPlanFinish());
						// }
					}
				}

			}
			// added by hba to save statistics info

			// save deviceUtilize 注释掉，在afterSchedule中自动保存
			/*
			 * try { List<SDevice> list = new ArrayList<SDevice>(); List<ScheduleUtilize>
			 * scheduleUtilizeList = new ArrayList<ScheduleUtilize>(); if
			 * (scheme.getDeviceMap() == null ||
			 * scheme.getDeviceMap().isEmpty()) { log.error("方案中无设备集合！");
			 * return; }
			 * 
			 * for (SDevice device : scheme.getDeviceMap().values()) { if
			 * (!device.getVirtual()) { String resUid = device.getDeviceUid();
			 * scheduleUtilizeList = scheduleUtilizeDao .getScheduleUtilizeList(
			 * scheme.getScheduleUid(), resUid); // 存在记录则更新数据并保存,否则新建记录并添加 if
			 * (scheduleUtilizeList != null && scheduleUtilizeList.size() > 0) { //
			 * 依次遍历更新数据 for (ScheduleUtilize scheduleUtilize :
			 * scheduleUtilizeList) { scheduleUtilize.setResUtilize(device
			 * .getAverageUtilRation()); scheduleUtilize.setResLoad(device
			 * .getAverageLoadRation()); scheduleUtilize.setTotalwaittime(device
			 * .getTotalWaitTime()); scheduleUtilize.setTotalovertime(device
			 * .getTotalOverTime()); scheduleUtilize.setTotalsetuptime(device
			 * .getTotalSetupTime()); scheduleUtilize.setTotalruntime(device
			 * .getTotalRunTime()); }
			 * scheduleUtilizeDao.update(scheduleUtilizeList); } else {
			 * ScheduleUtilize scheduleUtilize = new ScheduleUtilize();
			 * scheduleUtilize.setScheduleUid(scheme .getScheduleUid());
			 * scheduleUtilize.setResUid(device.getResUid());
			 * scheduleUtilize.setResUtilize(device .getAverageUtilRation());
			 * scheduleUtilize.setResLoad(device .getAverageLoadRation());
			 * scheduleUtilize.setTotalwaittime(device .getTotalWaitTime());
			 * scheduleUtilize.setTotalovertime(device .getTotalOverTime());
			 * scheduleUtilize.setTotalsetuptime(device .getTotalSetupTime());
			 * scheduleUtilize.setTotalruntime(device .getTotalRunTime());
			 * scheduleUtilize.setWorkcenterUid(device .getSWorkCenterUid());
			 * scheduleUtilize.setDeptUid(device.getDeptUid());
			 * scheduleUtilize.setSegmentNum("all");
			 * scheduleUtilizeDao.add(scheduleUtilize); } } } } catch (Exception
			 * e) { // TODO: handle exception log.error(e); throw new
			 * BaseBusinessException("设备利用率保存出错！"); }
			 */

			// save device overtime 注释掉，在afterSchedule中自动保存
			/*
			 * try { // 先清空原有的调度方案下各设备的加班信息 String scheduleUid =
			 * scheme.getScheduleUid(); List<ScheduleOverTime>
			 * scheduleOverTimeList = scheduleOverTimeDao
			 * .getScheduleOverTimeList(scheduleUid);
			 * scheduleOverTimeDao.delete(scheduleOverTimeList); List<ScheduleOverTime>
			 * overTimeList = scheme.getOverTimeList(); if (overTimeList != null &&
			 * overTimeList.size() > 0) { scheduleOverTimeDao.add(overTimeList); } }
			 * catch (Exception e) { // TODO: handle exception log.error(e);
			 * throw new BaseBusinessException("设备加班保存出错！"); } // save device
			 * overtime end
			 */
			// save schedule events
			try {
				List<ScheduleEvent> scheduleEventList = this.scheduleStateFind
						.findALlScheduleEvents(scheme, null, null, null, null,
								null);
				scheduleEventDao.update(scheduleEventList);
			} catch (Exception e) {
				// TODO: handle exception
				log.error(e);
				throw new BaseBusinessException("保存调度事件失败！");
			}
			// save schedule events end

			// hba

		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error(e);
			throw new BaseBusinessException("保存任务失败！");
		}
	}

	protected void delVirtualCalLink(ScheduleScheme scheme) {

		try {
			log.info("删除虚拟链接前总链接数量为：" + scheme.getAllOperationLinkMap().size());
			// 清除所有虚拟链接
			List<SOperationLink> vList = new ArrayList<SOperationLink>();
			for (SOperationLink l : scheme.getAllOperationLinkMap().values()) {
				if (log.isDebugEnabled()) {
					try {
						if (log.isDebugEnabled()) {
							if (l.getPredOperationTask().getTaskUid().equals(
									"8404402d-33ef-4e6a-9014-b43501261a36")
									&& l
											.getSuccOperationTask()
											.getTaskUid()
											.equals(
													"1befb5b5-386b-4922-b70f-20bceb188e79")) {
								log.debug(l.getPredOperationTask());
							}
						}
					} catch (RuntimeException e) {
						// TODO Auto-generated catch block
						// e.printStackTrace();
					}
				}
				if (l instanceof SVirtualLink) {

					SVirtualLink vLink = (SVirtualLink) l;
					if (!vLink.isPersistence())
						vList.add(l);

				}
			}

			for (SOperationLink vl : vList) {
				this.scheduleLinkManager.deleteLink(vl);
			}

			log
					.info("删除完虚拟链接后总链接数量为："
							+ scheme.getAllOperationLinkMap().size());
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			log.error("删除虚拟链接时发生错误!", e);
		}
	}

	/**
	 * 准备调度数据，一次调度过程中只运行一次
	 * 
	 * @param scheme
	 * @throws Exception
	 */
	public void prepareScheduleData(ScheduleScheme scheme) throws Exception {
		// 删除虚拟链接
		delVirtualCalLink(scheme);

		// 整理一下数据,主要原因是现在的调度集合好像存在bug
		// 会将待排产集合中的任务纳入调度
		// lqm todo
		// 将来应该移除
		tempErrorScheduleTaskPro(scheme);

		// 准备工序任务数据
		for (SOperationTask operationTask : scheme.getScheduleOperationTasks()) {
			// 保证大于0
			if (operationTask.getEstiTaskWork() <= 0)
				operationTask.setEstiTaskWork(scheme.getScheduleInterval()
						.doubleValue());
			if (log.isDebugEnabled()) {
				if (operationTask.getTaskUid().equals("4098890")) {
					log.debug("4098890");

				}
			}
			// 忽略非法的锁定
			if (operationTask.getLocked().equals(1)
					&& (operationTask.getPlanStart() == null || operationTask
							.getPlanFinish() == null)) {
				operationTask.setLocked(0);
			}

			// 缺省情况下计算锁定=锁定值
			operationTask.setCalLocked(operationTask.getLocked());

			// 保存上一次调度结果，仅用于做比较
			// lqmtodo,应该将设备preDeviceUid加上
			operationTask.setPrevPlanStart(operationTask.getPlanStart());
			operationTask.setPrevPlanFinish(operationTask.getPlanFinish());

			operationTask.setCalDeviceSeq(null);
			// 只需要初始化一次
			if (!this.scheduleOperationTaskManager
					.canChangeDevice(operationTask))
				operationTask
						.setCalFixedDeviceUid(operationTask.getDeviceUid());
			else
				operationTask.setCalFixedDeviceUid(null);

			if (operationTask.getGroupTask() != null)
				continue;

			// for (ResourceConstraint alterResource : operationTask
			// .getAlterResourceMap().values()) {
			// if (alterResource.getDevice() != null)
			// alterResource.getDevice().getMaybeTaskMap().put(
			// operationTask, alterResource.getPriority());
			// }

		}

		// 清除零件任务的完成时间
		for (SPartTask p : scheme.getSchedulePartTasks()) {
			p.setPlanStart(null);
			p.setPlanFinish(null);
			// 设置零件任务的最早投料时间
			// 现在是按照静态投料计算，所以只计算一次
			// lqm todo
			p.setControlEarlyStart(p.getEarlyStart());
		}

		// if (log.isDebugEnabled()) {
		// for (SDevice device : scheme.getDeviceMap().values()) {
		// log.debug("设备" + device.toString() + "可能队列大小"
		// + device.getMaybeTaskMap().size());
		// }
		// }

		// log.info("开始重置调度设备！");
		// 对第一次调度进行重置运算有些冗余
		// 对于sbt,没必要每次都清除设备队列
		for (SDevice device : scheme.getDeviceMap().values()) {
			device.getInterruptDeviceQueue().clear();
			// 清除由于序列而产生的SeqEarlyStartSegement
			device.setDeviceSeqEarlyStartSegement(0);
			// 初始时无论怎样都需要考虑其能力

			if (scheme.getCriticalLevel() != null
					&& device.getCriticalLevel() > scheme.getCriticalLevel())
				device.setCalIgnoreCapacityBoolean(true);
			else
				device.setCalIgnoreCapacityBoolean(false);

			if (device.getCalPreemptive())
				device.setCalPreemptive(false);

			// 初始时无论怎样都要允许分配到该设备上
			device.setCalForbiddenAppendAssign(false);
			// // 只需执行一次
			// device.setCalCapacityDevice(null);

		}

		scheme.setCalTaskSinkMap(null);
		log.debug("结束重置调度设备！");

	}

	/**
	 * 每次调度都自动处理
	 * 
	 * @param scheme
	 * @throws Exception
	 */

	public void clearScheduleResult(ScheduleScheme scheme) throws Exception {
		// 初始化当前调度任务顺序
		scheme.setTotalAssignCount(0);
		// 初始化当前调度任务顺序
		scheme.setTotalCancelAssignCount(0);
		// 设备清空 including wait time,setup time,task queue and so on
		this.resetDevice(scheme);
		// the real time of computer
		Date currentTime = scheme.getScheduleCurrentTime();
		for (SOperationTask operationTask : scheme.getScheduleOperationTasks()) {
			if (log.isDebugEnabled()) {
				if (operationTask.getTaskUid().equals(
						"40648aff-c7bc-4dc4-92c0-c5e89f3106f2")) {
					log.debug("aaaaaaaaa");
				}
			}

			if (log.isDebugEnabled()) {
				// log.info("任务 "+operationTask);
				// operationTask.setNotes(null);
			}

			// 以下三个均属于调度临时变量，便于做各种undo
			operationTask.setUseSegementList(new ArrayList<Integer>());
			operationTask.setAssignedResource(null);

			operationTask.setAssignState(SOperationTask.ASSNSTATE_WAITING);

			// 最小设置成当前时间
			// 只是用作移动瓶颈法临时
			// 因为中间用了一个
			// operationTask.setCalcEarlyStart(scheme.getScheduleCurrentTime());

			operationTask.setControlEarlyStart(scheme.getScheduleCurrentTime());
			operationTask
					.setControlEarlyFinish(scheme.getScheduleCurrentTime());
			// 总体调度次数
			operationTask.setScheduleCount(0);
			// 当前调度顺序
			operationTask.setScheduleOrder(0);

			// 锁定任务处理和设备队列处理
			// 只要未锁定则将其时间设置为空
			if (operationTask.getLocked() == 0 && !operationTask.isFinished()) {
				// 加入日历视图中调整的判断,调整后的不能清除其开始和结束 by hba
				if (operationTask.getManualScheduleState() == null
						|| operationTask.getManualScheduleState() == SOperationTask.MANUAL_UNSCHEDULED) {
					operationTask.setPlanStart(null);
					operationTask.setPlanFinish(null);
					operationTask.setPlanStartSegment(0);
					operationTask.setPlanFinishSegment(0);
				}
				if (this.scheduleOperationTaskManager
						.canChangeDevice(operationTask)) {
					operationTask.setDeviceUid(null);
					operationTask.setDevice(null);
				}
			}

		}

		log.debug("清除调度结果!");
	}

	public void deviceSeqPro(ScheduleScheme scheme) throws Exception {
		log.info("开始进行设备序列处理");
		// for (SDevice device : scheme.getDeviceMap().values()) {
		//
		// if (device.getAssignedTaskQueue() != null)
		// device.getAssignedTaskQueue().clear();
		// }
		// 先清除所有devicequeue链接

		// for (SDevice device : scheme.getDeviceMap().values()) {
		// // //
		// // device.setDeviceEarlyStartSegement(0);// 清0
		// if (device.getInterruptDeviceQueue().size() > 0)
		// device.getInterruptDeviceQueue().clear();
		// }

		// List<SOperationTask> interruptDeviceQueue;// = new
		// ArrayList<SOperationTask>();

		for (SOperationTask operationTask : scheme.getScheduleOperationTasks()) {
			// if (operationTask.getDrawingId().equals("p229")
			// && operationTask.getBatchNum().equals("2P1106")
			// && operationTask.getOperationIdDesc().equals("75")) {
			// log.debug(operationTask);
			//
			// }

			/*
			 * lqm 必须加上 operationTask.getGroupTask() == null
			 * 2013-4-23，因为在组合之前已经设置了一个序列， 组合之后又设置了一个序列 两者产生冲突导致调度出现死循环
			 */
			// 将其加入设备干扰序列
			if (operationTask.getDevice() != null
					&& (operationTask.getDevice().canUseSeq())
					&& operationTask.getGroupTask() == null) {
				// 已开始任务排在最前
				// todo
				// 与shorttermpro有些冲突
				// 以后再做改进，
				// 将各种状态都集中进caldeviceseq
				// 然后按照deviceseq
				// if(operationTask.isStarted())
				// operationTask.setCalDeviceSeq(-1);
				// else
				// 已开始任务设置为100
				if (operationTask.isStarted())
					operationTask.setCalDeviceSeq(19);
				else if (operationTask.getTaskState() == 2081)// 已中断的任务
					operationTask.setCalDeviceSeq(29);
				else if (operationTask.getTaskState() == 2069)// 已完成离线准备的任务
					operationTask.setCalDeviceSeq(39);
				if (operationTask.getDeviceSeq() != null
						&& operationTask.getDeviceSeq() > 0)
					operationTask.setCalDeviceSeq(100 + operationTask
							.getDeviceSeq());
				// //由于现场派工任务太乱，暂时屏蔽
				else if (operationTask.isDispatched()) {
					// 已派工任务排在设备序列任务之后
					operationTask.setCalDeviceSeq(Integer.MAX_VALUE);
				}

				if (operationTask.getCalDeviceSeq() != null
						&& operationTask.getCalDeviceSeq() > 0) {
					operationTask.getDevice().getInterruptDeviceQueue().add(
							operationTask);

					if (log.isDebugEnabled()) {
						if (operationTask.getDevice().getDeviceUid().equals(
								"3401017")) {
							log.debug("aaaaa");
						}

					}
				}
			}

		}

		// 产生链接

		// 预先设计device的干扰序列
		// 这段代码加上后避免中间过程一些取消派工的操作
		for (SDevice device : scheme.getDeviceMap().values()) {
			if (log.isDebugEnabled()) {
				if (device.getDeviceUid().equals("3401059")) {
					log.debug("aaaaa");
				}
				if (device.getDeviceUid().equals("3401017")) {
					log.debug("bbbbbbbb");
				}
			}

			List<SOperationTask> deviceTaskList = new ArrayList<SOperationTask>();
			deviceTaskList.addAll(device.getInterruptDeviceQueue());
			this.createDisjuctiveLink(device.getDeviceUid(), deviceTaskList); // 产生虚拟链接
			deviceTaskList = null;

			// lqm todo
			// 暂时setDeviceSeqEarlyStartSegement
			// 都由preassign中的refresh代替，所以这一部分已经没有意义了

			// TreeSet<SOperationTask> interruptDeviceQueue = device
			// .getInterruptDeviceQueue();
			// if (interruptDeviceQueue != null && interruptDeviceQueue.size() >
			// 0) {
			// double queueLength = 0;
			// for (SOperationTask operationTask : interruptDeviceQueue) {
			// queueLength += operationTask.getEstiTaskWork();
			// }
			// // 缺憾，就是未将已将已开始的任务统计在队列中
			// // lqm 20140425,已经解决，将开始任务设置为caldeviceseq为100的队列
			// int endSegement = this.deviceManager.calFinishSegement(device,
			// 0, queueLength);
			//
			// device.setDeviceSeqEarlyStartSegement(endSegement);
			//
			// }

		}

		log.info("结束进行设备序列处理deviceSeqPro");

	}

	protected List<SOperationLink> createDisjuctiveLink(String deviceUid,
			List<SOperationTask> deviceTaskList) {
		log.debug("开始根据设备序列产生虚拟链接createDisjuctiveLink");
		List<SOperationLink> links = new ArrayList<SOperationLink>();

		try {
			Map<Integer, List<SOperationTask>> map;

			if (deviceTaskList != null && deviceTaskList.size() > 1) {
				map = new LinkedHashMap<Integer, List<SOperationTask>>();
				for (SOperationTask so : deviceTaskList) {
					if (map.containsKey(so.getCalDeviceSeq())) {
						map.get(so.getCalDeviceSeq()).add(so);
					} else {
						List<SOperationTask> opTaskList = new ArrayList<SOperationTask>();
						opTaskList.add(so);
						map.put(so.getCalDeviceSeq(), opTaskList);
					}

				}
				List<SOperationTask> predOpTaskList = null;
				for (List<SOperationTask> opTaskList : map.values()) {
					if (predOpTaskList == null) {
						predOpTaskList = opTaskList;
						continue;
					}

					for (SOperationTask predSo : predOpTaskList) {
						for (SOperationTask succSo : opTaskList) {
							SDisjunctiveLink link = new SDisjunctiveLink();// 就只是这句话不一样
							link.setPredOperationTask(predSo);
							link.setSuccOperationTask(succSo);
							link.setFixedLink(true);// 属于计划员指定的链接，这个链接不能修改
							// 析取链接一定写上设备
							link.setDeviceUid(deviceUid);

							if (log.isDebugEnabled()) {
								log.info("创建虚拟链接，从" + predSo.getTaskUid()
										+ ",到" + succSo.getTaskUid());
							}

							try {
								this.scheduleLinkManager.addVirtualLink(link);

								links.add(link);
							} catch (Exception e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
					}

					predOpTaskList = opTaskList;

				}

				map = null;

			}
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			log.error("创建序列产生的虚拟链接时发生错误！", e);
		}
		log.debug("结束根据设备序列产生虚拟链接createDisjuctiveLink");
		return links;
	}

	/**
	 * 一次调度一次整理
	 * 
	 * @param scheme
	 * @param mode
	 * @throws Exception
	 */
	public void beforeSchedule(ScheduleScheme scheme, int mode)
			throws Exception {
		// 保持调度过程中统一的调度开始时间
		if (scheme.getScheduleCurrentTime() == null)
			scheme.setScheduleCurrentTime(new Date());
		// 设置任务比较器
		if (scheme.getOperationTaskComparator() == null)
			scheme.setOperationTaskComparator(new TaskScheduleComparator());
		// 准备调度数据，一次调度运算执行一次,delete virtual links
		this.prepareScheduleData(scheme);

		// 清除调度数据，每次调度迭代都执行一次 delete operation task info
		this.clearScheduleResult(scheme);

		// 设备队列处理
		try {
			this.deviceSeqPro(scheme);
		} catch (Exception e1) {
			// TODO Auto-generated catch block
			log.error("调度前置处理时发生错误！", e1);
		}

		// // this.initScheduleOperationTaskList(scheme);
		//
		// // lqm
		// // to,应该放在每次parttask,operationTask中更合理
		// // 现在放在这里便于减少计划员操作
		// // this.refreshSlackAndColor(scheme);
		//
		// this.resetDevice(scheme);
		//
		// // 清除所有虚拟链接
		// List<SOperationLink> vList=new ArrayList<SOperationLink>();
		// for (SOperationLink l : scheme.getAllOperationLinkMap().values()) {
		// if (l instanceof SVirtualLink) {
		// vList.add(l);
		//
		// }
		// }
		//
		// for(SOperationLink vl:vList)
		// {
		// this.scheduleLinkManager.deleteLink(vl);
		// }
		//
		// //清除临时分派顺序
		// //List<SVirtualLink> tempLinks=new ArrayList<SVirtualLink>();
		// //scheme.setTempAssnSortLinks(tempLinks);
		//
		// // 对当前时间的限制 //限制最早开始时间
		// Date currentTime = scheme.getScheduleCurrentTime();
		//
		// if (mode == 0) {
		// for (SOperationTask operationTask : scheme.getAllOperationTaskMap()
		// .values()) {
		// if (log.isDebugEnabled()) {
		// if (operationTask.getTaskUid().equals(
		// "e065f9e4-1f12-4ea0-9198-f7f11d6398b5")) {
		// log.debug("aaaaaaaaa");
		// }
		// }
		//		
		// //以下三个均属于调度临时变量，便于做各种undo
		// List<Integer> useSegementList=new ArrayList<Integer>();
		// operationTask.setUseSegementList(useSegementList);
		// operationTask.setAssignedResource(null);
		//
		// operationTask.setPrevPlanStart(operationTask.getPlanStart());
		// operationTask.setPrevPlanFinish(operationTask.getPlanFinish());
		//
		// operationTask.setAssignState(SOperationTask.ASSNSTATE_WAITING);
		// operationTask.setControlStart(currentTime);
		// // 锁定任务处理和设备队列处理
		// // 只要未锁定则将其时间设置为空
		// if (operationTask.getLocked() == 0
		// && !operationTask.isFinished()) {
		// operationTask.setPlanStart(null);
		// operationTask.setPlanFinish(null);
		// if (this.scheduleOperationTaskManager
		// .canChangeDevice(operationTask)) {
		// operationTask.setDeviceUid(null);
		// operationTask.setDevice(null);
		// }
		// }
		//
		// }
		// } else if (mode == 1) {/* 暂时基本无用 */
		//
		// for (SOperationTask operationTask : scheme
		// .getScheduleOperationTasks()) {
		//
		// if (operationTask.getDevice() != null
		// && operationTask.getPlanStart() != null
		// && operationTask.getPlanFinish() != null) {
		// // todo
		// // 这里实际上屏蔽了基于结果调度的功能
		// // this.assignManager.assignedSavedTask(operationTask,
		// // operationTask.getDevice());
		//
		// } else {
		// operationTask
		// .setAssignState(SOperationTask.ASSNSTATE_WAITING);
		// operationTask.setControlStart(scheme
		// .getScheduleCurrentTime());
		// }
		// }
		//
		// }
		// //整理一下数据,主要原因是现在的调度集合好像存在bug
		// //会将待排产集合中的任务纳入调度
		// tempErrorScheduleTaskPro(scheme);
		//
		// //初始化设备可能的任务队列
		//
		// for(SOperationTask operationTask:scheme.getScheduleOperationTasks())
		// {
		// if(operationTask.getGroupTask()!=null)continue;
		//
		// for(ResourceConstraint
		// alterResource:operationTask.getAlterResourceMap().values())
		// {
		// if(alterResource.getDevice()!=null)
		// alterResource.getDevice().getMaybeTaskMap().put(operationTask,
		// alterResource.getPriority());
		// }
		//	
		// }
		//
		// if(log.isDebugEnabled())
		// {
		// for(SDevice device:scheme.getDeviceMap().values())
		// {
		// log.info("设备可能队列大小"+device.getMaybeTaskMap().size());
		// }
		// }
		//
		//
		//

		// 只计算进入调度任务的松弛率
		// 由于设备队列调整引起了网络图的重新调整
		try {
			this.refreshScheduleSlackAndColor(scheme);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		log.info("结束调度前准备！");

	}

	/**
	 * 临时措施，处理调度任务
	 */
	private void tempErrorScheduleTaskPro(ScheduleScheme scheme) {
		Set<SPartTask> errorPartTaskSet = new HashSet<SPartTask>();
		for (SOperationTask operationTask : scheme.getScheduleOperationTasks()) {
			if (!operationTask.isRunning()) {
				SPartTask sp = operationTask.getParentTask();
				if (sp != null
						&& sp.getTaskScheduleState().equals(
								SPartTask.TASKSCHEDULESTATE_WAITING)) {
					errorPartTaskSet.add(sp);
					log.error("发现一个很严重的错误，待排产零件的工序任务进入调度." + operationTask);
				}
			}
		}

		for (SPartTask sp : errorPartTaskSet) {
			try {
				this.schedulePartTaskManager.outSchedule(sp);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		errorPartTaskSet = null;
	}

	// todo
	// 期待更强的短期微操
	public void shortTermPro(ScheduleScheme scheme) throws Exception {

		if (scheme.isAllowDeviceQueueInterrupt()) {

			for (SDevice device : scheme.getDeviceMap().values()) {
				device.setDeviceSeqEarlyStartSegement(0);// 清0
				if (device.getInterruptDeviceQueue().size() > 0)
					device.getInterruptDeviceQueue().clear();
			}

			for (SOperationTask operationTask : scheme
					.getScheduleOperationTasks()) {
				// if (operationTask.getDrawingId().equals("p229")
				// && operationTask.getBatchNum().equals("2P1106")
				// && operationTask.getOperationIdDesc().equals("75")) {
				// log.debug(operationTask);
				//
				// }

				/*
				 * lqm 必须加上 operationTask.getGroupTask() == null
				 * 2013-4-23，因为在组合之前已经设置了一个序列， 组合之后又设置了一个序列 两者产生冲突导致调度出现死循环
				 */
				if (operationTask.getCalDeviceSeq() != null
						&& operationTask.getCalDeviceSeq() > 0
						&& operationTask.getDevice() != null
						&& !(operationTask.getDevice() instanceof UcDevice)
						&& operationTask.getGroupTask() == null) {
					operationTask.getDevice().getInterruptDeviceQueue().add(
							operationTask);
				}
			}

			// 就让它顺其自然排
			// 先安排有设备序列的任务
			// TreeSet<Device> devices = deviceManager
			// .getDevicesOrderByCritical(scheme);
			// for (Device device : devices) {
			// if (device.getInterruptDeviceQueue().size() > 0) {
			// for (SOperationTask operationTask : device
			// .getInterruptDeviceQueue()) {
			// //todo
			// //lqm
			// //应该逆序排其前置工序任务
			// assignManager.assignTask(operationTask);
			//
			// }
			//
			// }
			// }
		}

	}

	/**
	 * 
	 * @param scheme
	 * @param mode
	 */
	public void schedule(ScheduleScheme scheme, int mode) {
		log.info("开始进行调度");
		long lStart = System.currentTimeMillis();

		// List<SOperationTask> currentOperationTaskList = null;

		// update scheduleStart
		// Calendar calendar = Calendar.getInstance();
		// // calendar.setTime(new Date());
		// // 设置调度的范围为四个月，应该放在参数中定义
		// scheme.setScheduleStart(calendar.getTime());
		// List<SPartTask> scheduleList = scheme.getPartTaskList();
		// assignLockTask(scheduleList);// 首先对已锁定任务进行调度

		// 一定要先将readytask初始化，再进行其它调度
		readyTaskManager.init(scheme);

		try {
			this.shortTermPro(scheme);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// //对外协任务进行统一处理，主要是处理协作任务的数据采集问题
		// for(SOperationTask operationTask :scheme.getReadyTaskS())
		// {
		// //外协任务判断
		// //todo,将来要增加对互相协作之间的工段进行判断
		// if((operationTask.getMasterShop()!=null&&!operationTask.getMasterShop().startsWith(scheme.getDeptUid())))
		// {
		// //如果时间在当前时间之后
		// if(operationTask.getPlanFinish()!=null&&operationTask.getPlanFinish().after(scheme.getScheduleStart()))
		// {
		// operationTask.setAssignState(SOperationTask.ASSNSTATE_SUCCESS);
		// try {
		// assignManager.afterAssign(operationTask);
		// } catch (Exception e) {
		// log.error("对锁定协作任务进行分配后处理时任务" + operationTask + "时发生异常" +
		// e.getMessage());
		// }
		//					
		//					
		// }
		// }
		// }

		// for (SPartTask partTask : scheduleList) {
		// for (SOperationTask operationTask : partTask.getOperationTaskList())
		// {
		// if (operationTask.getLocked() == 1) {
		// currentOperationTaskList.add(operationTask);
		// }
		// }
		// }
		// long i = 0, isuccess = 0;
		while (!readyTaskManager.isEmpty(scheme)) {
			// i++;
			SOperationTask operationTask = readyTaskManager
					.getFirstTask(scheme);
			if (log.isDebugEnabled()) {
				if (operationTask.getTaskUid().equals("3584016")) {
					log.debug(operationTask);
				}
			}
			// log.debug("开始调度第 " + i + "个任务," + scheduleTask);
			if (operationTask.getAssignState() == SOperationTask.ASSNSTATE_WAITING) {
				try {
					assignManager.assignTask(operationTask);
				} catch (Exception e) {
					// 设置成失败，防止scheduleManager中，readytaskmanager出现清除引起的死循环
					operationTask
							.setAssignState(SOperationTask.ASSNSTATE_FAILURE);
					log
							.error("分配任务" + operationTask + "时发生异常"
									+ e.getMessage());
					readyTaskManager.remove(scheme, operationTask);
				}

			} else { // if (scheduleTask.getAssignState() ==
				// SOperationTask.ASSNSTATE_SUCCESS
				// || scheduleTask.getAssignState() ==
				// SOperationTask.ASSNSTATE_FAILURE)
				// 保险，防止一些地方出现死循环
				readyTaskManager.remove(scheme, operationTask);
			}

		}
		if (log.isDebugEnabled()) {
			long lEnd = System.currentTimeMillis();
			long diff = (lEnd - lStart) / 1000;// 得到两者的毫秒数
			log.info("本次共调度结束！用时  " + diff + "  秒");

			log.info("本次调度次数为：" + scheme.getTotalAssignCount() + ",取消调度次数为："
					+ scheme.getTotalCancelAssignCount());

		}
	}

	public void calPartTaskTime(ScheduleScheme scheme) {
		for (SPartTask partTask : scheme.getSchedulePartTasks()) {
			this.setStartEndTimeOfPartTask(partTask);
		}
	}

	// 
	public void afterSchedule(ScheduleScheme scheme, int mode) {
		try {

			// 每次准备数据时已删，重复删除
			delVirtualCalLink(scheme);
			// 将设备利用率改成必须同步计算
			this.scheduleAnalysis.calDeviceStatistics(scheme);

			class AnalysisThread implements Runnable {

				private ScheduleAnalysis scheduleAnalysis;
				private ScheduleScheme scheme;

				AnalysisThread(ScheduleAnalysis scheduleAnalysis,
						ScheduleScheme scheme) {
					this.scheme = scheme;
					this.scheduleAnalysis = scheduleAnalysis;

				}

				public void run() {
					// TODO Auto-generated method stub
					if (log.isDebugEnabled()) {
						// Thread.currentThread().setName(
						// "调度分析线程 " + scheme.getScheduleUid());
					}

					try {
						scheduleAnalysis.analysis(scheme);

					} catch (Exception e) {
						// 设置成失败，防止scheduleManager中，readytaskmanager出现清除引起的死循环
						// operationTask.setAssignState(SOperationTask.ASSNSTATE_FAILURE);
						log.error("调度分析时发生异常" + e.getMessage());

					}
				}
			}
			;

			try {

				ExecutorService cachedExecutorService = SysUtil
						.getExecutorService();

				AnalysisThread analysisThread = new AnalysisThread(
						this.scheduleAnalysis, scheme);
				cachedExecutorService.submit(analysisThread);

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private void initDeviceCalendar(ScheduleScheme scheme) throws Exception {

		Map<String, SCalendar> calendarMap = scheme.getCalendarMap();

		for (SDevice device : scheme.getDeviceMap().values()) {
			if (log.isDebugEnabled()) {
				if (device.getDeviceUid().equals("cooperation")) {
					log.debug("aaaaaaaaaaaaaa");
				}
			}
			String calendarUid = device.getCalendarUid();
			if (calendarUid == null || calendarUid.equals("")) {
				calendarUid = scheme.getDefaultCalendarUid();
				device.setCalendarUid(calendarUid);
				log.debug(device + " 设置为调度缺省日历" + calendarUid);
			}
			// todo
			// 这里只是简单的防止了出错
			// 没对日历给出更详细的提示

			try {
				if (!calendarMap.containsKey(calendarUid)) {
					SCalendar scalendar = scheduleCalendarManager.initCalendar(
							scheme, calendarUid);
					calendarMap.put(calendarUid, scalendar);
					device.setCalendar(scalendar);
				} else
					device.setCalendar(calendarMap.get(calendarUid));
			} catch (Exception e) {
				log.error("调度日历初始化时发生错误,日历编号为：" + calendarUid + "\n"
						+ e.getMessage());
			}

			log.debug(device + "调度日历设置成功：" + calendarUid);

		}

	}

	public void resetDevice(ScheduleScheme scheme) {

		log.debug("开始重置调度设备！");
		// 对第一次调度进行重置运算有些冗余
		for (SDevice device : scheme.getDeviceMap().values()) {

			log.debug("开始重置设备：" + device.getDeviceName() + " "
					+ device.getDeviceUid());
			// if (device instanceof McDevice) {
			// for (SDevice vd : ((McDevice) device).getVirtualDeviceList()) {
			// resetDevice(vd);
			// }
			// return;
			// }
			// if (device instanceof MtDevice) {
			// for (DeviceTable dt : ((MtDevice) device).getTableList()) {
			// resetDevice(dt);
			// }
			// // return;//需要同时同步主资源，作为主轴资源
			// }
			device.setTotalWaitTime(0);
			device.setTotalSetupTime(0);
			// 清除运行时间统计
			device.setTotalRunTime(0);
			device.setNotRobustCount(0);
			device.setTotalUseCount(0);
			device.setTotalOverTime(0);
			// added by hba 用于重置设备加工时间
			// device.setTotalRunTime(0);

			// by lqm ,sbt没必要每次都清除
			// if (device.getInterruptDeviceQueue() != null
			// && device.getInterruptDeviceQueue().size() > 0)
			// device.getInterruptDeviceQueue().clear();
			// // 清除由于序列而产生的SeqEarlyStartSegement
			// device.setDeviceSeqEarlyStartSegement(0);

			// 清除每段的任务
			device.getSegementUseMap().clear();
			// 一定要清除已经派工队列
			device.getAssignedTaskQueue().clear();

			// int[] capacity = device.getCapacity();

			// if(device.getDeviceUid().equals("3401049-1"))
			// {
			// log.debug(device.getDeviceUid());
			// }
			//			
			// throw java.lang.ArrayIndexOutOfBoundsException :35168
			// for (int i = 0; i < capacity.length; i++) {
			// capacity[i] = Resource.RESOURCE_IDLE;
			// }
			log.debug("结束重置设备" + device.getDeviceName() + " "
					+ device.getDeviceUid());
		}
		log.debug("结束重置调度设备！");

	}

	// assign locked operation task ,plan start and plan finish are all given,as
	// well as device
	private void assignLockTask(List<SPartTask> partTaskList) {
		for (SPartTask partTask : partTaskList) {
			for (SOperationTask operationTask : partTask.getOperationTaskList()) {

				if (operationTask.getCalLocked() == 1) {

					try {
						this.assignManager.assignTask(operationTask);
					} catch (Exception e) {
						log.error("调度过程中发生错误！" + e.getMessage());
					}

				}
			}
		}
	}

	// get the task of the highest priority
	private SOperationTask getCurrentOperationTask(
			List<SOperationTask> operTaskList) {

		for (SOperationTask operationTask : operTaskList) {
			// 每次都计算controstart,有些浪费啊
			// todo
			this.scheduleOperationTaskManager
					.calcControlEarlyStart(operationTask);
			SPartTask parentTask = operationTask.getParentTask();
			schedulePartTaskManager.calcSlack(parentTask, operationTask);
		}

		Collections.sort(operTaskList, new Comparator<Object>() {
			public int compare(Object o1, Object o2) {
				SOperationTask operTask1 = (SOperationTask) o1;
				SOperationTask operTask2 = (SOperationTask) o2;
				int i = 0;
				// 都是锁定的情况下
				// 优先级越大表示越不重要
				// 同等优先级松弛率越大表示越不重要
				if (operTask1.getLocked() == operTask2.getLocked()) {

					if (operTask1.getPriority() > operTask2.getPriority()
							|| operTask1.getPriority() == operTask2
									.getPriority()
							&& operTask1.getSlackFactor() > operTask2
									.getSlackFactor()) {
						i = 1;
					}
				} else if (operTask2.getLocked() == 1)// 如果任务2锁定
					i = 1;
				return i;
			}
		});

		return operTaskList.get(0);
	}

	public Boolean update(ScheduleScheme arg) throws Exception {
		try {
			this.ScheduleSchemeDao.update(arg);
		} catch (BaseDBException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}

	public void initConstraint(ScheduleScheme scheme) throws Exception {
		// List<ScheduleConstraint> constrainList = this.STaskDao
		// .loadAllConstriant(scheme.getScheduleUid());
		// Set<SPartTask> splitedPartTaskSet = new HashSet<SPartTask>();
		// List<ScheduleConstraint> splitConstriantList = new
		// ArrayList<ScheduleConstraint>();
		// for (ScheduleConstraint scheduleConstraint : constrainList) {
		// switch (scheduleConstraint.getConstraintType()) {
		// case 1: {
		// String[] batchNums = scheduleConstraint.getBatchNum()
		// .split(",");
		// List<SPartTask> partTaskListToBeCombinedList = new
		// ArrayList<SPartTask>();
		// for (String batchNum : batchNums) {
		// for (SPartTask partTask : scheme.getAllPartTaskMap()
		// .values()) {
		// if (partTask.getPartUid().equals(
		// scheduleConstraint.getPartUid())
		// && partTask.getBatchNum().equals(batchNum)) {
		// partTaskListToBeCombinedList.add(partTask);
		// break;
		// }
		// }
		// }
		// if (partTaskListToBeCombinedList.size() > 0) {
		// SPartTask combinedBatch = this.schedulePartTaskManager
		// .combineBatch(partTaskListToBeCombinedList, 1);
		// // combinedBatch.setRootBatch(true);
		// //
		// // scheme.getAllPartTaskMap().put(combinedBatch.getTaskUid(),
		// // combinedBatch);
		// // for(SPartTask sp:combinedBatch.getCombinedBatchs())
		// // {
		// // scheme.getAllPartTaskMap().remove(sp.getTaskUid());
		// // }
		// //
		// // scheme.getCombineBatchList().add(combinedBatch);
		// }
		// break;
		// }
		// case 2: {
		// for (SPartTask partTask : scheme.getAllPartTaskMap().values()) {
		// if (partTask.getTaskUid().equals(
		// scheduleConstraint.getTaskUid())) {
		// partTask.setSplitStartOperId(scheduleConstraint
		// .getStartOperationIDDesc());
		// splitedPartTaskSet.add(partTask);
		//
		// break;
		// }
		// }
		// splitConstriantList.add(scheduleConstraint);
		// break;
		// }
		// case 3: {
		// for (SPartTask partTask : scheme.getAllPartTaskMap().values()) {
		// if (partTask.getPartUid().equals(
		// scheduleConstraint.getPartUid())
		// && partTask.getBatchNum().equals(
		// scheduleConstraint.getBatchNum())) {
		// this.schedulePartTaskManager.setPS(partTask,
		// scheduleConstraint.getStartOperationId(),
		// scheduleConstraint.getEndOperationId(),
		// scheduleConstraint.getTransferCount());
		//
		// break;
		// }
		// }
		//
		// break;
		// }
		// default:
		// break;
		// }
		// }
		// for (SPartTask partTask : splitedPartTaskSet) {
		// float splitStartOperationId = 0;
		// for (SOperationTask opTask : partTask.getOperationTaskList()) {
		// if (opTask.getOperationIDDesc().equals(
		// partTask.getSplitStartOperId())) {
		// splitStartOperationId = opTask.getOperationId();
		// }
		// }
		// List<SOperationTask> opTaskList = new ArrayList<SOperationTask>();
		// for (ScheduleConstraint constraint : splitConstriantList) {
		// if (constraint.getTaskUid().equals(partTask.getTaskUid())) {
		// SOperationTask temp = new SOperationTask();
		// temp.setBatchNum(constraint.getBatchNum());
		// temp.setPlanQty(constraint.getPlanQty());
		// temp.setLateFinish(constraint.getLateFinish());
		// temp.setCompleteQty(0);
		// temp.setOperationId(splitStartOperationId);
		// opTaskList.add(temp);
		// }
		// }
		// List<SPartTask> partTaskList = this.schedulePartTaskManager
		// .splitBatch(partTask, opTaskList);
		// for (SPartTask sp : partTaskList) {
		// scheme.getAllPartTaskMap().put(sp.getTaskUid(), sp);
		// }
		//
		// scheme.getAllPartTaskMap().remove(partTask);
		// scheme.getSplitedPartTaskList().add(partTask);
		// }

	}

	public void openScheme(ScheduleScheme scheme) throws BaseBusinessException,
			BaseDBException {
		// TODO Auto-generated method stub

		// update scheduleStart
		Calendar calendar = Calendar.getInstance();
		// calendar.setTime(new Date());
		// 设置调度的范围为四个月，应该放在参数中定义
		scheme.setScheduleStart(calendar.getTime());
		calendar.add(Calendar.MONTH, 4);
		scheme.setScheduleFinish(calendar.getTime());

		// 设置总调度时间段
		scheme.calTotalSegement();
		calendar.setTime(scheme.getScheduleStart());
		calendar.add(Calendar.DATE, scheme.getWatchDays());
		scheme.setWatchFinish(calendar.getTime());

		// load tasks or update tasks
		STaskDao.openTasks(scheme);

		// initialize device data
//		deviceDao.initDeviceMap(scheme);

		Map<String, List<OperationDevice>> operationDeviceList = null;
//				deviceDao.getOperationDeviceList(scheme);

		if (operationDeviceList == null || operationDeviceList.isEmpty()) {
			// lqm todo
			// 临时
			log.error("**严重警告:该部门没有发现任何设备约束!");
		}

		scheme.setOperationDeviceMap(operationDeviceList);

		// set task initial value
		Map<String, SPartTask> PartTaskMap = scheme.getAllPartTaskMap();
		Map<String, SOperationTask> operationTaskMap = scheme
				.getAllOperationTaskMap();
		Map<String, SOperationLink> operationLinkMap = scheme
				.getAllOperationLinkMap();

		for (SOperationTask operationTask : operationTaskMap.values()) {
			String parentTaskUid = operationTask.getParentTaskUid();
			if (PartTaskMap.containsKey(parentTaskUid)) {
				SPartTask parentTask = PartTaskMap.get(parentTaskUid);
				operationTask.setParentTask(parentTask);
				if (!operationTask.isFinished()) {
					parentTask.getOperationTaskList().add(operationTask);
				}
			}

			scheduleOperationTaskManager.calcAlterResourceList(operationTask);

			if (operationTask.getDeviceUid() != null) {
				SDevice device = scheme.getDeviceMap().get(
						operationTask.getDeviceUid());
				if (device != null) {
					operationTask.setDevice(device);
				}
			}

			log.debug(operationTask + "部门编号为:" + operationTask.getMasterShop()
					+ " 调度部门编号：" + scheme.getDeptUid());
			// if
			// (!operationTask.getMasterShop().startsWith(scheme.getDeptUid()))
			// {
			// operationTask.setDeviceClass("cooperationCenter");
			// // 应该分成几类工作中心
			// operationTask.setDeviceClassName("外协中心");
			// }

		}

		// create the links between the operations
		for (SOperationLink operationLink : operationLinkMap.values()) {
			String predTaskUid = operationLink.getPredecessorUid();
			String succTaskUid = operationLink.getSuccessorUid();
			SOperationTask predTask = null;
			SOperationTask succTask = null;
			if (operationTaskMap.containsKey(predTaskUid)) {
				predTask = operationTaskMap.get(predTaskUid);
			}
			if (operationTaskMap.containsKey(succTaskUid)) {
				succTask = operationTaskMap.get(succTaskUid);
			}
			if (predTask != null && succTask != null) {
				operationLink.setPredOperationTask(predTask);
				operationLink.setSuccOperationTask(succTask);
				predTask.getSuccLinkSet().add(operationLink);
				succTask.getPredLinkSet().add(operationLink);
			}
		}

		List<String> deletePartTaskUidList = new ArrayList<String>();
		for (SPartTask partTask : PartTaskMap.values()) {
			List<SOperationTask> operationTaskList = partTask
					.getOperationTaskList();
			if (operationTaskList.size() == 0) {
				deletePartTaskUidList.add(partTask.getTaskUid());
				continue;
			}
			partTask.sortByOperationId();
			// 存在问题，还是会出现影响当前link的现象

			// partTask
			// .setCurrentOperation(partTask.getOperationTaskList().get(0));
			if (partTask.getControlFinish() == null) {
				partTask.setControlFinish(scheme.getScheduleFinish());
			}
			int size = operationTaskList.size();
			operationTaskList.get(size - 1).setControlFinish(
					partTask.getControlFinish());
			schedulePartTaskManager.calcSlack(partTask);
			// 创建工序距离
			int i = 0;
			for (SOperationTask operationTask : partTask.getOperationTaskList()) {

				operationTask.setTaskDistance(i++);

			}

		}

		for (String str : deletePartTaskUidList) {
			scheme.getAllPartTaskMap().remove(str);
		}

		scheme.setSplitedPartTaskList(new ArrayList<SPartTask>());

		scheme.setGroupTaskList(new ArrayList<SOperationTask>());

	}

	/*
	 * private void refreshCombineBatch(ScheduleScheme scheme) { // 更新合批任务 List<SPartTask>
	 * combineBatchList = scheme.getCombineBatchList(); List<SPartTask>
	 * removedCombineBatchList = new ArrayList<SPartTask>(); List<SOperationTask>
	 * removedCombineOperationList; for (SPartTask combineBatch :
	 * combineBatchList) { removedCombineOperationList = new ArrayList<SOperationTask>();
	 * for (SOperationTask combineSo : combineBatch.getOperationTaskList()) {
	 * combineSo.setPlanQty(0d); combineSo.setCompleteQty(0d); for (SPartTask
	 * subBatch : combineBatch.getCombinedBatchs()) { SOperationTask subSo =
	 * subBatch.getByIddesc(combineSo .getOperationIdDesc()); if (subSo != null) {
	 * combineSo.setPlanQty(combineSo.getPlanQty() + subSo.getPlanQty());
	 * combineSo.setCompleteQty(combineSo.getCompleteQty() +
	 * subSo.getCompleteQty()); } } if (combineSo.getPlanQty() == 0 ||
	 * combineSo.getCompleteQty() >= combineSo.getPlanQty()) {
	 * removedCombineOperationList.add(combineSo); } else {
	 * combineSo.calTaskWork(); } }
	 * 
	 * for (SOperationTask combineSo : removedCombineOperationList) { //
	 * 移除一个节点的方法 try {
	 * scheduleOperationTaskManager.removeOperationTask(combineSo); } catch
	 * (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
	 * 
	 * if (combineBatch.getOperationTaskList().size() == 0) {
	 * removedCombineBatchList.add(combineBatch); } }
	 * 
	 * for (SPartTask combineBatch : removedCombineBatchList) {
	 * scheme.getAllPartTaskMap().remove(combineBatch); } }
	 */
	/**
	 * 零件任务数据预处理
	 */
	public void schemePartTaskPro(ScheduleScheme scheme) throws Exception {

		for (SPartTask partTask : scheme.getAllPartTaskMap().values()) {
			this.schedulePartTaskManager.init(scheme, partTask);

		}

		// for (String str : deletePartTaskUidList) {
		// scheme.getAllPartTaskMap().remove(str);
		// }
	}

	/**
	 * 工序任务处理
	 * 
	 * @param scheme
	 * @throws Exception
	 */
	public void schemeOperationTaskPro(ScheduleScheme scheme) throws Exception {

		try{
			
			System.out.println("2");
			for (SOperationTask operationTask : scheme.getAllOperationTaskMap()
					.values()) {
				if (operationTask.getTaskUid().equals(
						"b32c38a9-aa27-491d-8872-9d0a69504053"))
					log.debug(operationTask);

				this.scheduleOperationTaskManager.init(scheme, operationTask);
				
			}
		}catch (Exception e){
			e.printStackTrace();
		}

		// // 初始化临时任务
		// // todo
		// // 应该独立出来
		// for (SOperationTask operationTask : scheme.getScheduleTempTaskList())
		// {
		// // if (SOperationTask.TASKTYPE_TEMPTASK.equals(operationTask
		// // .getTaskType())) {
		// // // 先设置完后再计算可选资源
		// // // 或者将两者结合起来
		// // // todo
		// this.scheduleOperationTaskManager.init(scheme, operationTask);
		// // }
		//
		// }
		// // 应该独立出来
		// for (SOperationTask operationTask : scheme.getCoTaskMap().values()) {
		// // if (SOperationTask.TASKTYPE_TEMPTASK.equals(operationTask
		// // .getTaskType())) {
		// // // 先设置完后再计算可选资源
		// // // 或者将两者结合起来
		// // // todo
		// if(log.isDebugEnabled())
		// {
		// if(operationTask.getTaskUid().equals("ee507ef2-b948-4537-9e2c-4d8f1bf72a4e"))
		// log.debug("aaaaaaaaaaaaa");
		// }
		// this.scheduleOperationTaskManager.init(scheme, operationTask);
		// // }
		//
		// }

	}

	/**
	 * 链接数据预处理
	 * 
	 * @param scheme
	 */
	private void schemeLinkDataPro(ScheduleScheme scheme) {
		

		Map<String, SOperationLink> operationLinkMap = scheme
				.getAllOperationLinkMap();
		Map<String, SOperationTask> operationTaskMap = scheme
				.getAllOperationTaskMap();

		// create the links between the operations
		for (SOperationLink operationLink : operationLinkMap.values()) {
			String predTaskUid = operationLink.getPredecessorUid();
			String succTaskUid = operationLink.getSuccessorUid();
			SOperationTask predTask = null;
			SOperationTask succTask = null;
			if (operationTaskMap.containsKey(predTaskUid)) {
				predTask = operationTaskMap.get(predTaskUid);
			}
			if (operationTaskMap.containsKey(succTaskUid)) {
				succTask = operationTaskMap.get(succTaskUid);
			}

			if (predTask != null && succTask != null) {
				// 后续任务已经开始，则忽略所有链接
				if (succTask.isStarted())
					continue;
				operationLink.setPredOperationTask(predTask);
				operationLink.setSuccOperationTask(succTask);
				predTask.getSuccLinkSet().add(operationLink);
				succTask.getPredLinkSet().add(operationLink);
			}
		}
	}

	/**
	 * 初始化参数
	 * 
	 * @param scheme
	 */
	private void schemeParaPro(ScheduleScheme scheme) {
		try {

			// 暂时先放在这里 投入控制松弛系数
			if (scheme.getThrowInControSlack() != null
					&& scheme.getThrowInControSlack() > 0) {
				scheme.setAllowThrowInControl(true);
			}

			Calendar calendar = Calendar.getInstance();

			calendar.setTime(scheme.getScheduleStart());
			calendar.add(Calendar.DATE, scheme.getWatchDays());
			/**
			 * 设置scheme的观察结束时刻
			 */
			scheme.setWatchFinish(calendar.getTime());

			if (!"".equals(scheme.getDefaultCalendarUid())) {

				SCalendar scalendar = scheduleCalendarManager.initCalendar(
						scheme, scheme.getDefaultCalendarUid());
				scheme.getCalendarMap().put(scheme.getDefaultCalendarUid(),
						scalendar);
				scheme.setDefaultCalendar(scalendar);
			}

			if (scheme.getApplySTF() != null && scheme.getApplySTF()) {
				// lqm todo
				// 将来应该放到不同的调度结果方案中，对应用与是否应用这两种规则进行比较
				scheme.setOperationTaskComparator(new TaskScheduleComparatorSTF());
			} else {
				scheme.setOperationTaskComparator(new TaskScheduleComparator());
			}

		} catch (Exception e) {
			e.printStackTrace();
			log.error("调度参数初始化时发生错误！");
		}
	}

	private void schemeDataPro(ScheduleScheme scheme) {
		// update scheduleStart

		try {
			/**
			 * 非等效并行机的处理
			 */
			//取出的mapsize是11
			System.out.println("");
			Map<String, List<OperationDevice>> operationDeviceList = null;
//					deviceDao
//					.getOperationDeviceList(scheme);

			scheme.setOperationDeviceMap(operationDeviceList); // list放入map？

			/**
			 * 工序任务预处理
			 */
			//这里处理的有点问题，主要是estipreoptime 可能是空的
			schemeOperationTaskPro(scheme);
			/**
			 * 工序链接信息的预处理
			 */
			schemeLinkDataPro(scheme);
			/**
			 * 零件任务集合
			 */
			schemePartTaskPro(scheme);

			/**
			 * 初始化成组工序任务
			 */
			groupTaskPro(scheme);

			/**
			 * 初始化设备日历
			 */
			try {
				initDeviceCalendar(scheme);
			} catch (Exception e) {
				log.error("初始化日历时发生严重错误，调度可能无法进行！");
				throw e;
				// e.printStackTrace();
			}

			// 一定要先初始化调度零件任务集合
			this.initSchedulePartTaskList(scheme);
			// 初始化调度工序任务集合
			this.initScheduleOperationTaskList(scheme);

			// 加载日历轴
			// for (Device device : scheme.getDeviceMap().values()) {
			// this.deviceManager.initDevice(device);
			// }
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error("调度初始化时发生错误！");
		}
	}

	private void groupTaskPro(ScheduleScheme scheme) {
		for (SOperationTask sOperationTask : scheme.getAllOperationTaskMap().values()) {

			if (sOperationTask.getTaskUid().equals("72547c80-a68d-4063-83d7-ca8844de0e78")) {
				log.debug(sOperationTask.toFriendlyString());
			}

			if (sOperationTask.getGroupTaskUid() != null) {
				SGroupOperationTask g = (SGroupOperationTask) scheme
						.getAllOperationTaskMap().get(sOperationTask.getGroupTaskUid());
				if (g != null) {
					sOperationTask.setGroupTask(g);
					g.getMemberTasks().add(sOperationTask);

				}

			}
		}
		try {
			List<SOperationTask> deletedList = new ArrayList<SOperationTask>();
			for (SOperationTask so : scheme.getGroupTaskList()) {
				if (((SGroupOperationTask) so).getMemberTasks().size() < 2)
					deletedList.add(so);
			}

			for (SOperationTask so : deletedList) {
				this.scheduleOperationTaskManager
						.cancelGroupTask((SGroupOperationTask) so);
			}
			for (SOperationTask so : scheme.getGroupTaskList()) {
				scheduleOperationTaskManager.calcAlterResourceList(so);
				so.calTaskWork();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void initSystemCalendar(ScheduleScheme scheme) throws Exception {
		this.scheduleCalendarManager.initSystemDefaultCalendar(scheme);
		if (scheme.getDefaultCalendarUid() == null) {
			log.warn("没有定义调度缺省日历!将自动采用系统缺省日历");
			scheme
					.setDefaultCalendarUid(SCalendar.DEFAULT_CALENDAR_STANDARD_24H);
		}

		SCalendar c = this.scheduleCalendarManager.getCalendar(scheme, scheme
				.getDefaultCalendarUid());

		scheme.setDefaultCalendar(c);

	}

	/**
	 * 恢复调度方案
	 */
	public void restoreScheme(ScheduleScheme scheme) throws Exception {

		// load tasks or update tasks
		log.debug("开始恢复调度数据");

		/**
		 * 获得当前时间
		 */
		Date dtStart = Calendar.getInstance().getTime();
		/**
		 * 初始化参数
		 */
		//System.out.println("调度参数初始化时发生错误！   ");
		//日历定义错误,找不到日历编号：SYSDC24
		schemeParaPro(scheme);
		/**
		 * 初始化时间范围
		 */
		this.initScheduleScope(scheme, null, null);
		/**
		 * 初始化系统日历
		 */
		this.initSystemCalendar(scheme);
		/**
		 * 初始化虚拟资源
		 */
		this.initVirtualResource(scheme);
		/**
		 * 初始化工作中心列表
		 */
		initWorkCenterMap(scheme);
		/**
		 * 初始化设备列表
		 */
//		deviceDao.initDeviceMap(scheme);
		/**
		 * 初始化调度任务
		 */
		STaskDao.restoreTasks(scheme);
		/**
		 * 调度数据预处理
		 */
		schemeDataPro(scheme);
		/**
		 * 初始化系统颜色
		 */
		scheme.initColorMap();

		// 这段代码暂时放在操作执行完之后执行 hba

		// 如果基准计划不为空,从基准计划中继承
		if (StringUtils.isNotBlank(scheme.getBaseScheduleUid())) {
			//this.inheritBaseScheme(scheme);
		}
		// hba
		// 重新设置为已打开状态
		scheme.setScheduleState(ScheduleScheme.SCHEDULESTATE_OPENED);
		Date dtEnd = Calendar.getInstance().getTime();
		long diff = (dtEnd.getTime() - dtStart.getTime()) / 1000;// 得到两者的毫秒数
		log.info("结束恢复调度数据,本次恢复用时" + diff + "秒");

	}

	public void inheritBaseScheme(ScheduleScheme scheme) throws Exception {
		ScheduleScheme baseScheme = this.getScheduleByUid(scheme
				.getBaseScheduleUid());
		List<SOperationTask> baseScheduleTasks;

		log.info("aaaa");
		// 基准计划不是概要计划时也不需要继承
		if (baseScheme == null || !scheme.getSchemeType().equals("1"))
			return;

		// 基准计划处理
		if (scheme.getBaseScheduleMode() == null)
			scheme.setBaseScheduleMode(1);

		// Map<String, SPartTask> PartTaskMap = initPartTaskMap(scheme);
		Map<String, SOperationTask> OperationTaskMap = initOperationTaskMap(scheme);

		switch (scheme.getBaseScheduleMode()) {
		case 0:
			// 基准模式为无节点时，需要清除最早开始的约束
			// baseScheduleTasks = this.STaskDao
			// .getBaseScheduleOperationTaskList(baseScheme);
			// if (!baseScheduleTasks.isEmpty() && baseScheduleTasks.size() > 0)
			// {
			// for (SOperationTask baseOperationTask : baseScheduleTasks) {
			// SOperationTask operationTask = scheme
			// .getAllOperationTaskMap().get(
			// baseOperationTask.getTaskUid());
			// if (operationTask != null
			// && StringUtils.isNotBlank(baseOperationTask
			// .getDeviceUid())) {
			// operationTask.setLateFinish(null);
			// //
			// operationTask.setCalcLateFinish(baseOperationTask.getPlanFinish());
			// }
			// }
			// }

			break;
		case 1:
			// 基准计划任务 设置里程碑 此处使用taskUid可能会有问题，可以考虑使用图号、批次、工序号的map
			baseScheduleTasks = this.STaskDao
					.getBaseScheduleOperationTaskList(baseScheme);
			if (!baseScheduleTasks.isEmpty() && baseScheduleTasks.size() > 0) {
				for (SOperationTask baseOperationTask : baseScheduleTasks) {
					String opKey = baseOperationTask.getPartUid() + "_"
							+ baseOperationTask.getBatchNum() + "_"
							+ baseOperationTask.getOperationIdDesc();
					SOperationTask operationTask = OperationTaskMap.get(opKey);
					if (operationTask != null
							&& StringUtils.isNotBlank(baseOperationTask
									.getDeviceUid())) {
						operationTask.setLateFinish(baseOperationTask
								.getPlanFinish());
						// operationTask.setCalcLateFinish(baseOperationTask.getPlanFinish());
					}
				}
			}
			break;
		case 2:
			// 基准计划任务 设置锁定
			baseScheduleTasks = this.STaskDao
					.getBaseScheduleOperationTaskList(baseScheme);
			if (!baseScheduleTasks.isEmpty() && baseScheduleTasks.size() > 0) {
				for (SOperationTask baseOperationTask : baseScheduleTasks) {
					String opKey = baseOperationTask.getPartUid() + "_"
							+ baseOperationTask.getBatchNum() + "_"
							+ baseOperationTask.getOperationIdDesc();
					SOperationTask operationTask = OperationTaskMap.get(opKey);
					if (operationTask != null) {
						operationTask.setLocked(1);
						operationTask.setPlanStart(baseOperationTask
								.getPlanStart());
						operationTask.setPlanFinish(baseOperationTask
								.getPlanFinish());
						operationTask.setDeviceUid(baseOperationTask
								.getDeviceUid());
					}
				}
			}

			break;
		default: {
			break;
		}
		}
	}

	private void buildNet(ScheduleScheme scheme,
			List<SOperationTask> operationTaskList,
			List<SOperationLink> operationLinkList) {

		Map<String, SPartTask> PartTaskMap = scheme.getAllPartTaskMap();
		Map<String, SOperationTask> operationTaskMap = scheme
				.getAllOperationTaskMap();

		for (SOperationTask operationTask : operationTaskList) {
			String parentTaskUid = operationTask.getParentTaskUid();
			if (PartTaskMap.containsKey(parentTaskUid)) {
				SPartTask parentTask = PartTaskMap.get(parentTaskUid);
				operationTask.setParentTask(parentTask);
				parentTask.getOperationTaskList().add(operationTask);
			}
		}

		// create the links between the operations
		for (SOperationLink operationLink : operationLinkList) {
			String predTaskUid = operationLink.getPredecessorUid();
			String succTaskUid = operationLink.getSuccessorUid();
			SOperationTask predTask = null;
			SOperationTask succTask = null;
			if (operationTaskMap.containsKey(predTaskUid)) {
				predTask = operationTaskMap.get(predTaskUid);
			}
			if (operationTaskMap.containsKey(succTaskUid)) {
				succTask = operationTaskMap.get(succTaskUid);
			}
			if (predTask != null && succTask != null) {
				operationLink.setPredOperationTask(predTask);
				operationLink.setSuccOperationTask(succTask);
				predTask.getSuccLinkSet().add(operationLink);
				succTask.getPredLinkSet().add(operationLink);
			}
		}
	}

	 
	/**
	 * 初始化虚拟资源
	 */
	public void initVirtualResource(ScheduleScheme scheme) {
		Map<String, SWorkCenter> workCenterMap = scheme.getWorkCenterMap();
		SWorkCenter sw = new SWorkCenter();
		sw.setWorkCenterUid("cooperationCenter");
		sw.setWorkCenterName("外协中心");
		sw.setDeptUid("WX");
		sw.setDeptName("外协");
//		sw.setScheme(scheme);
//		sw.setVirtual(true);
		scheme.setVirtualCoWorkCenter(sw);

		workCenterMap.put(sw.getWorkCenterUid(), sw);
		log.debug("initDeviceMap" + "开始设置协作工作中心与协作设备");
		SDevice tempDevice = new UcDevice();
		tempDevice.setScheme(scheme);
		tempDevice.setDeviceUid("cooperation");
		tempDevice.setResUid("cooperation");
		tempDevice.setDeviceName("外协");
		tempDevice.setResName("外协");
		tempDevice.setDeviceClass("cooperationCenter");
		tempDevice.setDeviceClassName("外协中心");
		tempDevice.setResCapacity(1);
		if (scheme.getDefaultCalendar() != null) {
			tempDevice.setCalendar(scheme.getDefaultCalendar());
			tempDevice
					.setCalendarUid(tempDevice.getCalendar().getCalendarUid());
		}

		tempDevice.setVirtual(true);
		scheme.setVirtualCoDevice(tempDevice);
		scheme.getDeviceMap().put("cooperation", tempDevice);
	}

	public void initWorkCenterMap(ScheduleScheme scheme) throws Exception {
		Map<String, SWorkCenter> workCenterMap = scheme.getWorkCenterMap();
		List<WorkCenter> workCenterList = null;
//		this.workCenterDao
//				.getWorkCentersByDeptUid(scheme.getDeptUid(), null);
		if (workCenterList != null && workCenterList.size() > 0) {
			for (WorkCenter workCenter : workCenterList) {
				SWorkCenter sw = new SWorkCenter();
				sw.setWorkCenterUid(workCenter.getWorkCenterUid());
				sw.setWorkCenterName(workCenter.getWorkCenterName());
				sw.setDeptUid(workCenter.getDeptUid());
				sw.setDeptName(workCenter.getDept().getDeptName());
				if (workCenter.getCriticalLevel() == null)
					sw.setCriticalLevel((long)Device.CRITICALLEVEL_THIRD);
				else
					sw.setCriticalLevel(workCenter.getCriticalLevel().longValue());

//				sw.setScheme(scheme);
				workCenterMap.put(sw.getWorkCenterUid(), sw);
			}
		}

	}

	public ReadyTaskManager getReadyTaskManager() {
		return readyTaskManager;
	}

	public void setReadyTaskManager(ReadyTaskManager readyTaskManager) {
		this.readyTaskManager = readyTaskManager;
	}

	 
	public void applySchedulePara(ScheduleScheme newScheme,
			ScheduleScheme originScheme) throws Exception {
		// if (newScheme.getBaseScheduleUid() == null) {
		// originScheme.setBaseScheduleUid(null);
		// //originScheme.setBaseScheduleTasks(null);
		// } else if (!newScheme.getBaseScheduleUid().equals(
		// originScheme.getBaseScheduleUid())) {
		//			
		// this.in
		// this.inheritBaseScheme(scheme);
		// /
		// }

		if (newScheme.getCriticalLevel() == null)
			originScheme.setCriticalLevel(null);

		if (newScheme.getScheduleFinish() == null)
			originScheme.setScheduleFinish(null);

		// TODO Auto-generated method stub

		ObjectOperation.copyAttributes(newScheme, originScheme);
		this.update(originScheme);

		if (originScheme.getApplySTF() != null && originScheme.getApplySTF()) {
			// lqm todo
			// 将来应该放到不同的调度结果方案中，对应用与是否应用这两种规则进行比较
			originScheme
					.setOperationTaskComparator(new TaskScheduleComparatorSTF());
		} else {
			originScheme
					.setOperationTaskComparator(new TaskScheduleComparator());
		}

		try {
			if (originScheme.getDefaultCalendarUid() != null)
				originScheme.getVirtualCoDevice().setCalendar(
						this.scheduleCalendarManager.getCalendar(originScheme,
								originScheme.getDefaultCalendarUid()));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// 暂时对缺省日历的处理没有想好
		// if(newScheme.getDefaultCalendarUid()==null)
		// {
		// originScheme.setDefaultCalendarUid(null);
		// }
		// else
		// if(!newScheme.getDefaultCalendarUid().equals(originScheme.getDefaultCalendarUid()))
		// {
		// originScheme
		// }

	}

	public WorkCenterDao getWorkCenterDao() {
		return workCenterDao;
	}

	public void setWorkCenterDao(WorkCenterDao workCenterDao) {
		this.workCenterDao = workCenterDao;
	}

	/**
	 * @author SnowBear
	 * @param scheme
	 * @throws Exception
	 */
	public void refreshSlackAndColor(ScheduleScheme scheme){
	
		try{
			this.taskSFCalc.calcSF(scheme);
			this.priorityCalc.calcPriority(scheme);			
		}catch(Exception e){
			e.printStackTrace();
		}

		/**
		 * 计算指令的优先级，其实这一部分应该参数化
		 */

	}

	/**
	 * 只更改调度集合中的松弛率与色带
	 * 
	 * @param scheme
	 * @throws Exception
	 */
	public void refreshScheduleSlackAndColor(ScheduleScheme scheme)
			throws Exception {
		log.debug("计算调度松弛率！");
		this.taskSFCalc.calcScheduleSF(scheme);
		log.debug("计算调度优先级！");
		this.priorityCalc.calcSchedulePriority(scheme);

	}

	public TaskSFCalc getTaskSFCalc() {
		return taskSFCalc;
	}

	public void setTaskSFCalc(TaskSFCalc taskSFCalc) {
		this.taskSFCalc = taskSFCalc;
	}

	public PriorityCalc getPriorityCalc() {
		return priorityCalc;
	}

	public void setPriorityCalc(PriorityCalc priorityCalc) {
		this.priorityCalc = priorityCalc;
	}

	public ScheduleLinkManager getScheduleLinkManager() {
		return scheduleLinkManager;
	}

	public void setScheduleLinkManager(ScheduleLinkManager scheduleLinkManager) {
		this.scheduleLinkManager = scheduleLinkManager;
	}

	public ScheduleEventManager getScheduleEventManager() {
		return scheduleEventManager;
	}

	public void setScheduleEventManager(
			ScheduleEventManager scheduleEventManager) {
		this.scheduleEventManager = scheduleEventManager;
	}

	/**
	 * 初始化调度时间范围
	 */
	 
	public void initScheduleScope(ScheduleScheme scheme, Date scheduleStart,
			Date scheduleFinish) throws Exception {

		Calendar calendar = Calendar.getInstance();
		if (scheduleStart != null)
			calendar.setTime(scheduleStart);

		// 将小时与分钟减去
		calendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
		calendar.set(java.util.Calendar.MINUTE, 0);
		calendar.set(java.util.Calendar.SECOND, 0);
		calendar.set(java.util.Calendar.MILLISECOND, 0);

		// calendar.setTime(new Date());
		// 设置调度的范围为四个月，应该放在参数中定义
		// todo
		scheme.setScheduleStart(calendar.getTime());

		if (scheduleFinish == null) {
			calendar.add(Calendar.MONTH, 12);
		} else {
			// 下面暂时不支持
			calendar.setTime(scheduleFinish);

			// 将小时与分钟减去
			calendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
			calendar.set(java.util.Calendar.MINUTE, 0);
			calendar.set(java.util.Calendar.SECOND, 0);
			calendar.set(java.util.Calendar.MILLISECOND, 0);
		}
		scheme.setScheduleFinish(calendar.getTime());
		// 设置总调度时间段
		if (scheme.getScheduleInterval() == null)
			scheme.setScheduleInterval(10);
		scheme.calTotalSegement();
	}

	 
	public void setScheduleCurrentTime(ScheduleScheme scheme,
			Date scheduleCurrentTime) throws Exception {
		if (scheduleCurrentTime != null) {
			// 重新初始化调度范围
			this.initScheduleScope(scheme, scheduleCurrentTime, null);
			// 重新初始化调度日历
			this.scheduleCalendarManager.reInitSchemeCalendar(scheme);
			// if (scheduleCurrentTime.before(scheme.getScheduleStart())
			// || scheduleCurrentTime.after(scheme.getScheduleFinish()))
			// return;// 设置错误
		}
		scheme.setScheduleCurrentTime(scheduleCurrentTime);

		// 应该还有动态扩大调度时间区间的功能
		// 实时滚动区也应该有此功能，也还没有做
		// todo

	}

	/**
	 * 返回已经进入调度的工序任务列表 todo lqm 应该避免频繁过滤，
	 * 
	 * @return the partTaskList
	 */
	private void initScheduleOperationTaskList(ScheduleScheme scheme) {
		Map<String, SOperationTask> allOperationTaskMap = scheme
				.getAllOperationTaskMap();
		if (allOperationTaskMap == null)
			return;
		Set<SOperationTask> operationTaskList = scheme
				.getScheduleOperationTasks();
		operationTaskList.clear();
		for (SOperationTask operationTask : allOperationTaskMap.values()) {
			if (log.isDebugEnabled()) {
				if (operationTask.getTaskUid().equals(
						"d256227b-d460-44f6-9068-8ca9fe38cb4e")) {
					log.debug(operationTask.toFriendlyString());
				}

			}

			if (operationTask.getTaskScheduleState() == SOperationTask.TASKSCHEDULESTATE_STARTED)
				operationTaskList.add(operationTask);
		}

		// for (SPartTask partTask : scheme.getSchedulePartTasks()) {
		// for (SOperationTask operationTask : partTask.getOperationTaskList())
		// {
		// if (!operationTask.isFinished())
		// operationTaskList.add(operationTask);
		// }
		// }
		//
		// // 临时任务
		// for (SOperationTask operationTask : scheme.getScheduleTempTaskList())
		// {
		// if (operationTask.getTaskScheduleState() ==
		// SOperationTask.TASKSCHEDULESTATE_STARTED)
		// operationTaskList.add(operationTask);
		//
		// }
		// // 协作任务
		// for (SOperationTask operationTask : scheme.getCoTaskMap().values()) {
		// if (operationTask.getTaskScheduleState() ==
		// SOperationTask.TASKSCHEDULESTATE_STARTED)
		// operationTaskList.add(operationTask);
		//
		// }
		//		
		//		
		// for (SOperationTask operationTask : operationTaskList) {
		// if(operationTask.getTaskUid().equals("72547c80-a68d-4063-83d7-ca8844de0e78"))
		// {
		// log.debug("aaaaaaaaaaaaaaaaaaaaa");
		// }
		// if (operationTask.getGroupTask()!=null)
		// operationTaskList.add(operationTask.getGroupTask());
		//
		// }

	}

	/**
	 * 返回已经进入调度的零件任务列表 todo lqm 应该避免频繁过滤，
	 * 
	 * @return the partTaskList
	 */
	private void initSchedulePartTaskList(ScheduleScheme scheme) {
		Map<String, SPartTask> allPartTaskMap = scheme.getAllPartTaskMap();
		if (allPartTaskMap == null)
			return;
		Set<SPartTask> partTaskList = scheme.getSchedulePartTasks();
		partTaskList.clear();
		for (SPartTask partTask : allPartTaskMap.values()) {
			if (log.isDebugEnabled()) {
				if (partTask.getTaskUid().equals(
						"d256227b-d460-44f6-9068-8ca9fe38cb4e")) {
					log.debug(partTask.toFriendlyString());
				}

			}

			if (partTask.getTaskScheduleState() == SPartTask.TASKSCHEDULESTATE_STARTED)
				partTaskList.add(partTask);
		}

	}

	 
	public void createDeviceVLink(ScheduleScheme scheme) {
		Map<String, List<SOperationTask>> deviceActionTaskMap = new HashMap<String, List<SOperationTask>>();
		for (SDevice device : scheme.getDeviceMap().values()) {
			if (device.getVirtual())
				continue;
			List<SOperationTask> operationTaskList = new ArrayList<SOperationTask>();
			deviceActionTaskMap.put(device.getDeviceUid(), operationTaskList);
		}

		for (SOperationTask operationTask : scheme.getAllOperationTaskMap()
				.values()) {
			if (operationTask.getDeviceUid() != null
					&& (operationTask.getTaskState() == 206
							|| operationTask.getTaskState() == 2061
							|| operationTask.getTaskState() == 2069
							|| operationTask.getTaskState() == 207
							|| operationTask.getTaskState() == 2071
							|| operationTask.getTaskState() == 2072
							|| operationTask.getTaskState() == 2073
							|| operationTask.getTaskState() == 208 || operationTask
							.getTaskState() == 2081)) {
				deviceActionTaskMap.get(operationTask.getDeviceUid()).add(
						operationTask);
			}

		}

		for (List<SOperationTask> operationTaskList : deviceActionTaskMap
				.values()) {

			this.createDeviceVLink(operationTaskList);

		}

		deviceActionTaskMap = null;
	}

	@Deprecated
	private void createDeviceVLink(List<SOperationTask> operationTaskList) {
		if (operationTaskList != null && operationTaskList.size() > 0)
			return;

		Collections.sort(operationTaskList, new Comparator<SOperationTask>() {
			public int compare(SOperationTask operTask1,
					SOperationTask operTask2) {
				int i = -1;
				if (operTask1.equals(operTask2))
					return 0;
				if (operTask2.isStarted())// 如果第二项任务已经开始，则无论如何都向后放
					i = 1;
				else if (operTask1.getCalDeviceSeq().compareTo(
						operTask2.getCalDeviceSeq()) == 0) { // 同样的设备队列的情况下，按照优先顺序排
					if (operTask1.getPriority() > operTask2.getPriority())
						i = 1;
					else if (operTask1.getPriority().compareTo(
							operTask2.getPriority()) == 0) {

						if (operTask1.getDelayCost() < operTask2.getDelayCost())
							i = 1;
						else if (operTask1.getDelayCost().compareTo(
								operTask2.getDelayCost()) == 0) {

							if (operTask1.getSlackFactor() > operTask2
									.getSlackFactor())
								i = 1;
						}
					}

				}
				return i;
			}
		});

		for (int i = 0; i < operationTaskList.size() - 1; i++) {
			try {

				SDisjunctiveLink link = new SDisjunctiveLink();// 就只是这句话不一样
				link.setPredOperationTask(operationTaskList.get(i));
				link.setSuccOperationTask(operationTaskList.get(i + 1));
				link.setFixedLink(true);// 属于计划员指定的链接
				this.scheduleLinkManager.addVirtualLink(link);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	/**
	 * calculate the plan start time and plan finish time of a part task
	 * 
	 * @param partTask
	 */
	private void setStartEndTimeOfPartTask(SPartTask partTask) {
		log.debug("setStartEndTimeOfPartTask开始设置零件任务计划开始结束时间:" + partTask);
		List<SOperationTask> operationTaskList = partTask
				.getOperationTaskList();
		boolean bSuccess = true;
		if (partTask.getTaskUid()
				.equals("889f5d8f-f5a8-466f-bd32-ce22383c5cb5")) {
			log.debug("asdasdsdas");
		}
		if (operationTaskList == null || operationTaskList.size() == 0)
			return;

		try {
			Iterator<SOperationTask> iterator = operationTaskList.iterator();
			// todo
			// 这里存在问题
			Date planStart = partTask.getScheme().getScheduleFinish();
			Date planFinish = partTask.getScheme().getScheduleStart();

			SOperationTask prevOperationTask = null;
			while (iterator.hasNext()) {
				SOperationTask operationTask = iterator.next();
				if (operationTask.getAssignState() != null
						&& operationTask.getAssignState() == SOperationTask.ASSNSTATE_SUCCESS) {
					if (operationTask.getPlanStart() != null
							&& operationTask.getPlanFinish() != null) {
						if (operationTask.getPlanStart().before(planStart)) {
							planStart = operationTask.getPlanStart();
						}
						if (operationTask.getPlanFinish().after(planFinish)) {
							planFinish = operationTask.getPlanFinish();
						}

						if (log.isDebugEnabled()) {
							try {
								if (prevOperationTask != null
										&& prevOperationTask.getPlanFinish() != null
										&& prevOperationTask.getCompleteQty() == 0
										&& (operationTask.getLocked() != null && operationTask
												.getLocked() != 1)
										&& this.scheduleLinkManager.isPredTask(
												prevOperationTask,
												operationTask)
										&& prevOperationTask
												.getPlanFinish()
												.after(
														operationTask
																.getPlanFinish()))
									log.error("严重错误，前道工序在后道工序之后完成，error"
											+ prevOperationTask
													.toFriendlyString());
								else {

								}
							} catch (Exception e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}

						}

					} else
						log.error("调度成功任务计划开始与结束不能为空！" + operationTask);
				} else {
					bSuccess = false;
					break;
				}
				prevOperationTask = operationTask;

			}

			if (!bSuccess) {
				planStart = null;
				planFinish = null;
				log.warn("零组件任务:" + partTask + "调度失败！");
			}
			partTask.setPlanStart(planStart);
			partTask.setPlanFinish(planFinish);

			// 更新子批的完成日期
			if (partTask.getTaskScheduleType().equals(
					SPartTask.TASKSCHEDULETYPE_COMBINEBATCH)) {
				for (SPartTask childPartTask : partTask.getCombinedBatchs()) {
					childPartTask.setPlanStart(planStart);
					childPartTask.setPlanFinish(planFinish);
				}
			}

		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	protected void throwInControl(ScheduleScheme scheme) {
		try {
			if (!scheme.getAllowThrowInControl()
					|| scheme.getThrowInControSlack() == null)
				return;

			double throwInControlSlack = scheme.getThrowInControSlack();// ==
			// null
			// ?
			// 3:
			// scheme.getThrowInControSlack();

			for (SPartTask partTask : scheme.getSchedulePartTasks()) {
				// 对零件任务交货期为空的任务暂时不予处理
				if (partTask.getLateFinish() == null)
					continue;
				if (partTask.getSlackFactor() < throwInControlSlack)
					continue;

				// SOperationTask firstOperationTask =
				// partTask.getOperationTaskList()
				// .get(0);

				// if(firstOperationTask==null)
				// continue;
				//
				double remainWork = 0d;
				for (SOperationTask so : partTask.getOperationTaskList()) {
					remainWork += so.getEstiTaskWork();
				}
				//
				//
				// if (log.isDebugEnabled()) {
				// if (firstOperationTask.getTaskUid().equals(
				// "5efff716-4763-4aaf-a0c7-b521213a829f")) {
				// log.debug(firstOperationTask);
				// }
				// }
				// if (operationTask.getGroupTask() != null)
				// operationTask = operationTask.getGroupTask();

				// if (operationTask.getCheckPoint() == null
				// || operationTask.getCheckPoint().getCheckTime() == null
				// || operationTask.getRemainWork() == null)
				// continue;

				// // 看看是否首道工序
				// boolean isFirst = true;
				//
				// for (SOperationLink pl : operationTask.getPredLinkSet()) {
				// if (!(pl instanceof SVirtualLink)) {
				// isFirst = false;
				// break;
				//
				// }
				// }
				//
				// if (isFirst) {
				Date dtEarlyStart = new Date(partTask.getLateFinish().getTime()
						- (int) (throwInControlSlack * remainWork) * 60000);
				partTask.setControlEarlyStart(dtEarlyStart);
			}

			// }
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			log.error("计算投入产出比时发生错误！", e);
		}

	}

	public String getAlgorithmName() {
		return algorithmName;
	}

	public void setAlgorithmName(String algorithmName) {
		this.algorithmName = algorithmName;
	}

	 
	public void schedulePhase(ScheduleScheme scheme) {

	}

	 
	public void destroyScheme(ScheduleScheme scheme) {
		// TODO Auto-generated method stub
		scheme.destroy();
		scheme = null;
	}

	// 为中间的调度方案并行clone出一个新的调度方案
	public ScheduleScheme cloneCalScheme(ScheduleScheme scheme) {
		// TODO Auto-generated method stub
		ScheduleScheme newScheme = null;
		try {
			// newScheme = (ScheduleScheme)scheme.clone();

			newScheme = new ScheduleScheme();
			ObjectOperation.copyAttributes(scheme, newScheme);

			// 这些变量与每次调度无关，所以依然可以重用
			newScheme.setVirtualCoDevice(scheme.getVirtualCoDevice());
			newScheme.setVirtualCoWorkCenter(scheme.getVirtualCoWorkCenter());
			newScheme.setOperationDeviceMap(scheme.getOperationDeviceMap());
			newScheme.setCalendarMap(scheme.getCalendarMap());
			newScheme.setDefaultCalendar(scheme.getDefaultCalendar());
			newScheme.setOperationTaskComparator(scheme
					.getOperationTaskComparator());
			newScheme.setNotes("clone体");

			for (SDevice device : scheme.getDeviceMap().values()) {
				// SDevice newDevice=new SDevice();
				// 避免设备的多种类型
				SDevice newDevice = (SDevice) Class.forName(
						device.getClass().getName()).newInstance();
				ObjectOperation.copyAttributes(device, newDevice);

				newDevice.setCalendar(device.getCalendar());
				newDevice.setScheme(newScheme);
				newScheme.getDeviceMap().put(device.getDeviceUid(), newDevice);
			}
			// 处理虚拟设备
			for (SDevice device : scheme.getDeviceMap().values()) {

				if (device instanceof MtDevice) {
					MtDevice newDevice = (MtDevice) newScheme.getDeviceMap()
							.get(device.getDeviceUid());
					for (DeviceTable table : (((MtDevice) device)
							.getTableList())) {

						newDevice.getTableList().add(
								(DeviceTable) newScheme.getDeviceMap().get(
										table.getDeviceUid()));

					}

					newDevice.generateCombineResource();
				} else if (device instanceof McDevice) {
					McDevice newDevice = (McDevice) newScheme.getDeviceMap()
							.get(device.getDeviceUid());
					for (SDevice vr : ((McDevice) device)
							.getVirtualDeviceList()) {

						newDevice.getVirtualDeviceList()
								.add(
										newScheme.getDeviceMap().get(
												vr.getDeviceUid()));

					}
				}

				// if(device.getCalCapacityDevice()!=null)
				// {
				// SDevice newDevice = (SDevice) newScheme.getDeviceMap()
				// .get(device.getDeviceUid());
				//					
				// newDevice.setCalCapacityDevice(newScheme.getDeviceMap()
				// .get(device.getCalCapacityDevice().getDeviceUid()));
				// }

			}
			for (SPartTask PartTask : scheme.getSchedulePartTasks()) {
				// SPartTask newPartTask=(SPartTask)PartTask.clone();
				SPartTask newPartTask = new SPartTask();
				ObjectOperation.copyAttributes(PartTask, newPartTask);

				// 日历均可以共用

				newScheme.getAllPartTaskMap().put(newPartTask.getTaskUid(),
						newPartTask);
				newPartTask.setScheme(newScheme);
				newScheme.getSchedulePartTasks().add(newPartTask);
			}

			// for(OperationDevice
			// operationDevice:scheme.getOperationDeviceMap().values())
			// {
			// newScheme.getDeviceMap().put(device.getDeviceUid(),(SDevice)device.clone());
			// }
			for (SOperationTask operationTask : scheme
					.getScheduleOperationTasks()) {
				// SOperationTask
				// newOperationTask=(SOperationTask)operationTask.clone();
				SOperationTask newOperationTask = new SOperationTask();
				ObjectOperation.copyAttributes(operationTask, newOperationTask);

				// 日历均可以共用
				newOperationTask.setCalendar(operationTask.getCalendar());

				if (newOperationTask.getParentTaskUid() != null)
					newOperationTask.setParentTask(newScheme
							.getAllPartTaskMap().get(
									newOperationTask.getParentTaskUid()));

				for (Entry<String, ResourceConstraint> entry : operationTask
						.getAlterResourceMap().entrySet()) {
					ResourceConstraint newResourceConstraint = new ResourceConstraint();
					ObjectOperation.copyAttributes(entry.getValue(),
							newResourceConstraint);
					newResourceConstraint.setDevice(newScheme.getDeviceMap()
							.get(newResourceConstraint.getDeviceUid()));
					newOperationTask.getAlterResourceMap().put(entry.getKey(),
							newResourceConstraint);
				}
				newScheme.getAllOperationTaskMap().put(
						newOperationTask.getTaskUid(), newOperationTask);
				newOperationTask.setScheme(newScheme);
				newScheme.getScheduleOperationTasks().add(newOperationTask);
			}

			for (SPartTask partTask : scheme.getSchedulePartTasks()) {
				// SPartTask newPartTask=(SPartTask)PartTask.clone();
				SPartTask newPartTask = newScheme.getAllPartTaskMap().get(
						partTask.getTaskUid());

				for (SOperationTask operationTask : partTask
						.getOperationTaskList()) {
					newPartTask.getOperationTaskList().add(
							newScheme.getAllOperationTaskMap().get(
									operationTask.getTaskUid()));
				}
			}

			for (SOperationLink operationLink : scheme.getAllOperationLinkMap()
					.values()) {
				// SOperationLink
				// newOperationLink=(SOperationLink)operationLink.clone();

				SOperationLink newOperationLink = (SOperationLink) operationLink
						.clone();
				if (log.isDebugEnabled()) {
					if (newOperationLink instanceof SDisjunctiveLink) {
						SDisjunctiveLink tmp = (SDisjunctiveLink) newOperationLink;
						// log.info(tmp.getDeviceUid());

					}
				}
				// ObjectOperation.copyAttributes(operationLink,
				// newOperationLink);

				SOperationTask predSo = newScheme.getAllOperationTaskMap().get(
						newOperationLink.getPredecessorUid());
				SOperationTask succSo = newScheme.getAllOperationTaskMap().get(
						newOperationLink.getSuccessorUid());
				if (predSo == null || succSo == null) {
					log.debug("error,新clone链接任务不存在！");
					continue;
				}

				newOperationLink.setPredOperationTask(predSo);
				newOperationLink.setSuccOperationTask(succSo);

				predSo.getSuccLinkSet().add(newOperationLink);
				succSo.getPredLinkSet().add(newOperationLink);

				newOperationLink.setScheme(newScheme);
				newScheme.getAllOperationLinkMap().put(
						newOperationLink.getLinkKey(), newOperationLink);

			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error("克隆调度方案时出错！", e);
		}

		return newScheme;
	}

	 
	public void addDeptScheme(ScheduleScheme scheme)
			throws Exception {
		try {
			String deptId = ""; //SysUtil.getSessionDeptId();
			if (deptId == null || deptId.isEmpty())
				throw new BaseBusinessException("部门编号不能为空！请重新登录");

			if (scheme.getScheduleType() == null)
				scheme.setScheduleType(6);// 表示能力计划
			scheme.setScheduleState(ScheduleScheme.SCHEDULESTATE_CLOSED);
			scheme.setDeptUid(deptId);
			scheme.setScheduleUid(ScheduleUtils.getScheduleUid(deptId));

		} catch (Exception e) {
			e.printStackTrace();
		}

		this.add(scheme);
	}

	public void copyScheduleResult(ScheduleScheme fromScheme,
			ScheduleScheme toScheme) {

		for (SPartTask partTask : fromScheme.getSchedulePartTasks()) {
			SPartTask toPartTask = toScheme.getAllPartTaskMap().get(
					partTask.getTaskUid());

			toPartTask.setPlanStart(partTask.getPlanStart());
			toPartTask.setPlanFinish(partTask.getPlanFinish());
		}

		for (SOperationTask operationTask : fromScheme
				.getScheduleOperationTasks()) {
			SOperationTask toOperationTask = toScheme.getAllOperationTaskMap()
					.get(operationTask.getTaskUid());
			toOperationTask.setPlanStart(operationTask.getPlanStart());
			toOperationTask.setPlanFinish(operationTask.getPlanFinish());
			toOperationTask.setDevice(operationTask.getDevice());
			toOperationTask.setDeviceUid(operationTask.getDeviceUid());
		}
	}

	/**
	 * 用线程池来分配任务,没有考虑线程池上限， lqm todo,应该考虑上限的情况下独立出一个函数
	 * 
	 * @param operationTasks
	 * @param executorService
	 */
	protected void assnTasks(List<SOperationTask> operationTasks,
			ExecutorService executorService) {
		class AssnTaskThread implements Runnable {
			private SOperationTask operationTask;
			private AssignManager assignManager;
			private CountDownLatch latch;

			AssnTaskThread(SOperationTask operationTask,
					AssignManager assignManager, CountDownLatch latch) {
				this.operationTask = operationTask;

				this.assignManager = assignManager;
				this.latch = latch;

			}

			public void run() {
				if (log.isDebugEnabled()) {
					Thread.currentThread().setName(
							"任务调度线程" + operationTask.toFriendlyString());
				}
				try {
					if (log.isDebugEnabled()) {
						if (operationTask.getTaskUid().equals(
								"11D8F2305851423D836E22CE158EECFF")

						) {
							log.debug(operationTask);
						}
					}
					assignManager.assignTask(operationTask);
				} catch (Exception e) {
					// 设置成失败，防止scheduleManager中，readytaskmanager出现清除引起的死循环
					// operationTask.setAssignState(SOperationTask.ASSNSTATE_FAILURE);
					log
							.error("分配任务" + operationTask + "时发生异常"
									+ e.getMessage());

				} finally {
					latch.countDown();
				}
			}
		}
		;

		try {
			CountDownLatch latch = new CountDownLatch(operationTasks.size());

			for (SOperationTask operationTask : operationTasks) {
				AssnTaskThread assnTaskThread = new AssnTaskThread(
						operationTask, this.assignManager, latch);
				executorService.submit(assnTaskThread);

			}
			latch.await();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @see com.mes.schedule.manager.iface.ScheduleAlgorithm#doScheduleThreadPool(com.mes.schedule.persistence.domain.ScheduleScheme,
	 *      int)
	 */
	 
	public List<ScheduleResult> doScheduleThreadPool(ScheduleScheme scheme,
			int mode) throws Exception {
		// 对aps应用高级的线程策略
		ExecutorService executorService = null;
		try {
			executorService = ScheduleUtils.getExecutorService(scheme);

			if (executorService == null) {
				if (this.threadType == THREAD_TYPE_FIXED10)
					// 这个是114现在用的方法，怕引起效率问题，故采用
					executorService = Executors.newFixedThreadPool(10);
				else if (this.threadType == THREAD_TYPE_FIXED20)
					// 这个是114现在用的方法，怕引起效率问题，故采用
					executorService = Executors.newFixedThreadPool(20);
				else if (this.threadType == THREAD_TYPE_FIXED50)
					executorService = Executors.newFixedThreadPool(50);
				else if (this.threadType == THREAD_TYPE_UNLIMITED)
					executorService = Executors.newCachedThreadPool();
				else
					executorService = Executors.newFixedThreadPool(10);

				ScheduleUtils.setExecutorService(scheme, executorService);
			}

			return this.doSchedule(scheme, mode);
		} catch (RuntimeException e) {
			log.error(e);
			throw (e);
		} finally {
			// 最后关掉线程池
			ScheduleUtils.closeExecutorService(scheme);

		}

	}

	/**
	 * 创建一个Map，里面记录工序与所有交货节点之间的关系
	 * 
	 * @param scheme
	 * @return
	 */
	public Map<String, Set<TaskSink>> createTaskSink(ScheduleScheme scheme) {
		log.debug("开始创建任务对应目标createTaskSink");
		Map<String, Set<TaskSink>> taskSinkMap = new HashMap<String, Set<TaskSink>>();
		for (SPartTask partTask : scheme.getAllPartTaskMap().values()) {
			if (partTask.getLateFinish() != null
					&& partTask.getOperationTaskList().size() > 0) {
				SOperationTask sinkTask = partTask.getOperationTaskList().get(
						partTask.getOperationTaskList().size() - 1);
				// Date d = new Date(sinkTask
				// .getCalcEarlyStart().getTime()
				// + sinkTask.getEstiTaskWork().intValue() *
				// ScheduleUtils.MillSecondsOfMinute);
				//				
				Date d = partTask.getLateFinish();
				Set<SOperationLink> trackLinks = new HashSet<SOperationLink>();
				this.createTaskSink(sinkTask, d, sinkTask, partTask
						.getDelayCost().doubleValue() / 100, taskSinkMap,
						trackLinks);
			}
		}
		scheme.setCalTaskSinkMap(taskSinkMap);
		log.debug("结束创建任务对应目标createTaskSink");

		return taskSinkMap;
	}

	/*
	 * 改进之一：最早开始影响松弛率 (non-Javadoc)
	 * 
	 * @see com.mes.schedule.algorithm.iface.TaskSFCalc#calcSFForTimeSpot(com.mes.schedule.persistence.domain.SOperationTask)
	 */
	private void createTaskSink(SOperationTask operationTask, Date lateFinish,
			SOperationTask sinkTask, double sinkWeight,
			Map<String, Set<TaskSink>> taskSinkMap,
			Set<SOperationLink> trackLinks) {
		if (null == sinkTask || null == sinkTask.getCalcLateFinish())
			return;

		TaskSink taskSink = null;

		Set<TaskSink> taskSinkList = taskSinkMap.get(operationTask);
		if (taskSinkList == null) {
			taskSinkList = new HashSet<TaskSink>();
			taskSinkMap.put(operationTask.getTaskUid(), taskSinkList);
		} else {
			// 要加上防止循环的算法
			for (TaskSink oldTaskSink : taskSinkList) {
				if (oldTaskSink.getSink().equals(sinkTask)) {

					if (oldTaskSink.getLateFinish().before(lateFinish))
						return;

					taskSink = oldTaskSink;
					taskSink.setLateFinish(lateFinish);
					break;

				}
			}

		}

		if (taskSink == null) {
			taskSink = new TaskSink();
			taskSink.setSink(sinkTask);
			taskSink.setSinkWeight(sinkWeight);
			taskSink.setOperationTask(operationTask);
			taskSink.setLateFinish(lateFinish);

			taskSinkList.add(taskSink);
		}

		lateFinish = new Date(lateFinish.getTime()
				- (operationTask.getEstiTaskWork()).intValue()
				* ScheduleUtils.MillSecondsOfMinute);
		if (operationTask.getCalcEarlyStart() != null
				&& lateFinish.before(operationTask.getCalcEarlyStart()))
			lateFinish = (Date) operationTask.getCalcEarlyStart().clone();

		for (SOperationLink tmp : operationTask.getPredLinkSet()) {
			if (trackLinks.contains(tmp)) {
				// 已经走过的链接不让再走
				break;
			} else {
				trackLinks.add(tmp);
			}
			SOperationTask predOperationTask = tmp.getPredOperationTask();

			this.createTaskSink(predOperationTask, lateFinish, sinkTask,
					sinkWeight, taskSinkMap, trackLinks);
		}

	}

	// by hba
	 
	public List<ScheduleScheme> getScheduleByDeptId(String deptId,
			String schemeType) {
		// TODO Auto-generated method stub
		List<ScheduleScheme> list = this.ScheduleSchemeDao.findSchemeByDeptIdAndType(
				deptId, schemeType);
		return list;
	}

	// public ScheduleOverTimeDao getScheduleOverTimeDao() {
	// return scheduleOverTimeDao;
	// }
	//
	// public void setScheduleOverTimeDao(ScheduleOverTimeDao
	// scheduleOverTimeDao) {
	// this.scheduleOverTimeDao = scheduleOverTimeDao;
	// }
	//
	// public ScheduleEventDao getScheduleEventDao() {
	// return scheduleEventDao;
	// }
	//
	// public void setScheduleEventDao(ScheduleEventDao scheduleEventDao) {
	// this.scheduleEventDao = scheduleEventDao;
	// }

	public ScheduleStateFind getScheduleStateFind() {
		return scheduleStateFind;
	}

	public void setScheduleStateFind(ScheduleStateFind scheduleStateFind) {
		this.scheduleStateFind = scheduleStateFind;
	}

	public ScheduleOverTimeDao getScheduleOverTimeDao() {
		return scheduleOverTimeDao;
	}

	public void setScheduleOverTimeDao(ScheduleOverTimeDao scheduleOverTimeDao) {
		this.scheduleOverTimeDao = scheduleOverTimeDao;
	}

	public ScheduleEventDao getScheduleEventDao() {
		return scheduleEventDao;
	}

	public void setScheduleEventDao(ScheduleEventDao scheduleEventDao) {
		this.scheduleEventDao = scheduleEventDao;
	}

	 
	public void newScheduleSchemeOnBase(ScheduleScheme newScheme) {

		if (newScheme.getBaseScheduleUid() == null)
			return;
		try {
			this.STaskDao.exportScheduleScheme(newScheme
					.getBaseScheduleUid(), newScheme.getScheduleUid());

			this.STaskDao.ScheduleSchemeBaseFilter(newScheme);

			// this.openScheme(newScheme);
		} catch (Exception e) {

			// TODO Auto-generated catch block
			e.printStackTrace();

		}

		// for(SPartTask sp:)
		// TODO Auto-generated method stub

	}

	 
	public void newScheduleSchemeBasedOnOrigin(ScheduleScheme newScheme) {

		if (newScheme.getBaseScheduleUid() == null) {

		}
		// return;
		try {
			String originScheduleUid = "schedule-" + newScheme.getDeptUid();
			this.STaskDao.exportScheduleScheme(originScheduleUid,
					newScheme.getScheduleUid());

			this.STaskDao.ScheduleSchemeBaseFilter(newScheme);

			// this.openScheme(newScheme);
		} catch (Exception e) {

			// TODO Auto-generated catch block
			e.printStackTrace();

		}

		// for(SPartTask sp:)
		// TODO Auto-generated method stub

	}

	 
	public void restoreSchemeToOrigin(ScheduleScheme scheme) {

		// TODO Auto-generated method stub
		try {
			// 恢复之前先将数据清空

			// List<SOperationLink> linkLists = new ArrayList<SOperationLink>();
			// List<SOperationTask> opTaskLists = new
			// ArrayList<SOperationTask>();
			// List<SPartTask> partTaskLists = new ArrayList<SPartTask>();
			// linkLists =
			// this.scheduleLinkManager.findByProperty("scheduleUid",
			// scheme.getScheduleUid());
			// opTaskLists = this.scheduleOperationTaskManager.findByProperty(
			// "scheduleUid", scheme.getScheduleUid());
			// partTaskLists = this.schedulePartTaskManager.findByProperty(
			// "scheduleUid", scheme.getScheduleUid());
			//
			//			
			//			
			// this.scheduleLinkManager.delete(linkLists);
			// this.scheduleOperationTaskManager.delete(opTaskLists);
			// this.schedulePartTaskManager.delete(partTaskLists);

			this.STaskDao.clearScheduelData(scheme.getScheduleUid());
			String originScheduleUid = "schedule-" + scheme.getDeptUid();
			this.STaskDao.exportScheduleScheme(originScheduleUid, scheme
					.getScheduleUid());
			// 清除调度集合
			scheme.getAllOperationLinkMap().clear();
			scheme.getAllOperationTaskMap().clear();
			scheme.getAllPartTaskMap().clear();
			scheme.getScheduleOperationTasks().clear();
			scheme.getSchedulePartTasks().clear();
			this.restoreScheme(scheme);
			// this.openScheme(newScheme);
		} catch (Exception e) {

			// TODO Auto-generated catch block
			e.printStackTrace();

		} finally {

		}

	}

	 
	public List<ScheduleScheme> getScheduleByBaseScheduleUid(
			String baseScheduleUid) {

		// TODO Auto-generated method stub
		List<ScheduleScheme> list = this.ScheduleSchemeDao
				.findSchemeByBaseScheduleUid(baseScheduleUid);
		return list;
	}

	// public TaskBCManager getTaskBCManager() {
	// return taskBCManager;
	// }
	//
	// public void setTaskBCManager(TaskBCManager taskBCManager) {
	// this.taskBCManager = taskBCManager;
	// }
	/*
	 * 建立工序任务的part_number,batchnum,operation_iddesc map 便于快速查找
	 */
	private Map<String, SOperationTask> initOperationTaskMap(
			ScheduleScheme scheme) {
		Map<String, SOperationTask> OperationTaskMap = new HashMap<String, SOperationTask>();
		for (SOperationTask so : scheme.getAllOperationTaskMap().values()) {
			try {
				if (log.isDebugEnabled()) {
					if (so.getTaskUid().equals(
							"8dbf9025-1c69-4872-bf79-7da29994e5e0"))
						log.debug("aaaaaaaaaaaaaaa");
				}
				if (so.getPartUid() != null && so.getBatchNum() != null
						&& so.getOperationIdDesc() != null) {
					String[] strBatchNums = so.getBatchNum().split(",");
					String[] strOperations = so.getOperationIdDesc().split("/");
					for (int i = 0; i < strBatchNums.length; i++) {
						String strBatchNum = strBatchNums[i];

						// 只取第一道工序
						// String strKey = so.getPartUid() + "_" + strBatchNum
						// + "_" + strOperations[0];
						// OperationTaskMap.put(strKey, so);
						// 后面的工序都近来,反而会将状态混乱
						// 这样虽然会有最后一个零件的风险,但问题应该不大
						// todo
						for (int j = 0; j < strOperations.length; j++) {
							String strOperationIddesc = strOperations[j];

							String strKey = so.getPartUid() + "_" + strBatchNum
									+ "_" + strOperationIddesc;
							OperationTaskMap.put(strKey, so);
						}
						OperationTaskMap.put(so.getPartUid() + "_"
								+ so.getBatchNum() + "_"
								+ so.getOperationIdDesc(), so);
					}
				} else {
					log.warn("工序信息不完整，任务号：" + so);
				}
			} catch (RuntimeException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		return OperationTaskMap;
	}

	/*
	 * 建立零件任务的part_number,batchnum map 便于快速查找
	 */
	private Map<String, SPartTask> initPartTaskMap(ScheduleScheme scheme) {
		Map<String, SPartTask> PartTaskMap = new HashMap<String, SPartTask>();
		for (SPartTask st : scheme.getAllPartTaskMap().values()) {
			try {
				if (st.getPartUid() != null && st.getBatchNum() != null) {
					String strKey = st.getPartUid() + "_" + st.getBatchNum();
					PartTaskMap.put(strKey, st);

				} else {
					log.warn("信息不完整，任务号：" + st);
				}
			} catch (RuntimeException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		return PartTaskMap;
	}
	public String getRuleScheduleuid(int type) throws BaseBusinessException {
		return null;
	}

	@Override
	public void restoreSummaryScheme(ScheduleScheme scheme) throws Exception {
		// TODO Auto-generated method stub
		
	}
	
}
